ifstream 没有完全读取整个数据
ifstream does not completely read whole data
我正在尝试逐块读取文件。块大小为 64Byte。但是还剩下一些字节。
示例:我有一个 360 字节的文件并以 64 字节的块读取数据,所以我需要 6 次 64 字节的块来获取所有数据。
typedef unsigned char uint1;
ifstream is(path.c_str(), ifstream::in | ifstream::binary);
uint1 data[64];
int i = 0;
while (is.read((char*)data, 64)) {
i++;
}
cout << i << endl;
但是我只得到了 5 次完全填充的 64 字节块。如何获取剩余的Bytes??
我想问题是你的文件大小不能被缓冲区大小整除,所以最后一个块的大小小于 64(360 - 64 * 5 = 40 字节)。对于这种情况,istream::read 的文档说:
If the input sequence runs out of characters to extract (i.e., the end-of-file is reached) before n characters have been successfully read, the array pointed to by s contains all the characters read until that point, and both the eofbit and failbit flags are set for the stream.
因此,最后一个 is.read 的 return 值被评估为 "false" 并且您的计数器不计算它。
360不能被64整除,也就是说最后一个block不会被完整读取。咨询 suitable documentation 表明读取这样一个不完整的块会在您正在读取的流上设置 eofbit
和 failbit
,这意味着 while
循环中的条件将评估最后一个块到 false
。但是读取 did 确实发生了并且 数据存储正确。
您可能想在上次读取后检查 gcount()
的值:
while (is.read((char*)data, 64)) {
i++;
}
if (is.gcount() > 0) {
i++;
}
如果您的目标实际上是读取文件,而不是像示例那样简单地计算块数,那么您可能需要这样的东西:
std::ifstream is( path.c_str(), std::ios_base::binary ); // in mode is always set for ifstream
if( !is )
throw std::runtime_error("unable to open file '" + path + "'" );
while( !is.eof() )
{
std::array< char, 64 > buf;
is.peek(); // needs this because of the buffering.
const auto n = is.readsome( buf.data(), buf.size() );
if( is )
handle_block( buf, n ); // std::cout.write( buf.data(), n )
else
throw std::runtime_error("error reading file '" + path + "'" );
}
我正在尝试逐块读取文件。块大小为 64Byte。但是还剩下一些字节。
示例:我有一个 360 字节的文件并以 64 字节的块读取数据,所以我需要 6 次 64 字节的块来获取所有数据。
typedef unsigned char uint1;
ifstream is(path.c_str(), ifstream::in | ifstream::binary);
uint1 data[64];
int i = 0;
while (is.read((char*)data, 64)) {
i++;
}
cout << i << endl;
但是我只得到了 5 次完全填充的 64 字节块。如何获取剩余的Bytes??
我想问题是你的文件大小不能被缓冲区大小整除,所以最后一个块的大小小于 64(360 - 64 * 5 = 40 字节)。对于这种情况,istream::read 的文档说:
If the input sequence runs out of characters to extract (i.e., the end-of-file is reached) before n characters have been successfully read, the array pointed to by s contains all the characters read until that point, and both the eofbit and failbit flags are set for the stream.
因此,最后一个 is.read 的 return 值被评估为 "false" 并且您的计数器不计算它。
360不能被64整除,也就是说最后一个block不会被完整读取。咨询 suitable documentation 表明读取这样一个不完整的块会在您正在读取的流上设置 eofbit
和 failbit
,这意味着 while
循环中的条件将评估最后一个块到 false
。但是读取 did 确实发生了并且 数据存储正确。
您可能想在上次读取后检查 gcount()
的值:
while (is.read((char*)data, 64)) {
i++;
}
if (is.gcount() > 0) {
i++;
}
如果您的目标实际上是读取文件,而不是像示例那样简单地计算块数,那么您可能需要这样的东西:
std::ifstream is( path.c_str(), std::ios_base::binary ); // in mode is always set for ifstream
if( !is )
throw std::runtime_error("unable to open file '" + path + "'" );
while( !is.eof() )
{
std::array< char, 64 > buf;
is.peek(); // needs this because of the buffering.
const auto n = is.readsome( buf.data(), buf.size() );
if( is )
handle_block( buf, n ); // std::cout.write( buf.data(), n )
else
throw std::runtime_error("error reading file '" + path + "'" );
}