【问题标题】:ifstream does not completely read whole dataifstream 没有完全读取整个数据
【发布时间】:2015-10-30 21:38:38
【问题描述】:

我正在尝试逐块读取文件。块大小为 64 字节。但是还剩下一些字节。

示例:我有一个 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??

【问题讨论】:

  • 最后“i”的值是多少?
  • 最后"i"的值为5
  • 特别感谢 ValeryShevchuk 和 Angew

标签: c++ byte ifstream


【解决方案1】:

我想问题是你的文件大小不能被缓冲区大小整除,所以最后一个块的大小小于 64(360 - 64 * 5 = 40 字节)。对于这种情况,istream::read 的文档说:

如果在 n 个字符被成功读取之前输入序列用完了要提取的字符(即到达文件末尾),则 s 指向的数组包含直到该点读取的所有字符,并且两者为流设置了 eofbit 和 failbit 标志。

因此,last is.read 的返回值被评估为“false”,并且不计入您的计数器。

【讨论】:

  • 是的,我知道。有没有简单的方法可以将文件的数据加载到块中?
  • @tbol,您的最后一个块已正确加载,但您必须检查使用“istream::gcount”从流中读取了多少字节,因此您可以安全地使用第一个 istream::gcount() 字节在你的“数据”数组中
  • 非常感谢,字节已明确存储。
【解决方案2】:

360 不能被 64 整除,这意味着最后一个块不会被完整读取。咨询suitable documentation 表明读取这样一个不完整的块会在您正在读取的流上设置eofbitfailbit,这意味着您的while 循环中的条件将评估为最后一个块的false .但是读取确实确实发生了并且数据被正确存储。

您可能想在最后一次读取后检查gcount() 的值:

while (is.read((char*)data, 64)) {        
    i++;
}
if (is.gcount() > 0) {
    i++;
}

【讨论】:

    【解决方案3】:

    如果您的目标实际上是读取文件,而不是像样本那样简单地计算块数,那么您可能想要这样的东西:

    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 + "'" ); 
    } 
    

    【讨论】:

    • 我的目标是从文件中读取字节,并且我已经使用计数器来获取读取是否成功的响应。我只是忘了检查最后一个字节块是否真的被读取了。所以谢谢你的帮助,但我现在已经有了读取字节的解决方案。
    猜你喜欢
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多