我正在尝试逐块读取文件。 Blocksize是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;
但是我只得到完全填充的64字节块的5倍。如何获取剩余的字节?
答案 0 :(得分:4)
我认为问题是你的文件大小不能被缓冲区大小整除,所以最后一个块的大小小于64(360 - 64 * 5 = 40字节)。对于这种情况,istream::read的文档说:
如果在成功读取n个字符之前输入序列用完了要提取的字符(即,到达文件结尾),则s指向的数组包含直到该点读取的所有字符,并且为流设置了eofbit和failbit标志。
因此,最后is.read的返回值被评估为“false”,并且您的计数器不计算它。
答案 1 :(得分:3)
360不能被64整除,这意味着最后一个块将不会被完整读取。咨询suitable documentation表明,阅读这样一个不完整的块会在您正在阅读的流上设置eofbit
和failbit
,这意味着您的while
循环中的条件会进行评估到最后一个块的false
。但是读取确实发生了并且数据存储正确。
您可能想要在上次阅读后检查gcount()
的值:
while (is.read((char*)data, 64)) {
i++;
}
if (is.gcount() > 0) {
i++;
}
答案 2 :(得分:0)
如果您的目标实际上是阅读文件,而不是简单地计算样本所做的块数,那么您可能想要这样的smth:
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 + "'" );
}