ifstream.eof() - 在真正结束之前到达文件末尾

Posted

技术标签:

【中文标题】ifstream.eof() - 在真正结束之前到达文件末尾【英文标题】:ifstream.eof() - end of file is reached before the real end 【发布时间】:2013-02-08 15:37:49 【问题描述】:

我有一个大约 11.1G 的二进制文件,其中存储了来自 Kinect 的一系列深度帧。此文件中有 19437 帧。为了每次读取一帧,我在 fstream 中使用 ifstream 但它达到了 eof 在文件真正的结尾之前。 (我只得到了前 20 帧,由于 eof 标志,函数停止了)

但是,可以改为使用 stdio 中的 fread 来读取所有帧。

谁能解释一下这种情况?感谢您在我的问题上花费宝贵的时间。

这是我的两个函数:

// ifstream.read() - Does Not Work: the loop will stop after 20th frame because of the eof flag
ifstream depthStream("fileName.dat");
if(depthStream.is_open())

  while(!depthStream.eof())
  
    char* buffer = new char[640*480*2];
    depthStream.read(buffer, 640*480*2);

    // Store the buffer data in OpenCV Mat

    delete[] buffer;
  


// fread() - Work: Get 19437 frames successfully
FILE* depthStream
depthStream = fopen("fileName.dat", "rb");
if(depthStream != NULL)

  while(!feof(depthStream))
  
    char* buffer = new char[640*480*2];
    fread(buffer, 1, 640*480*2, depthStream);

    // Store the buffer data in OpenCV Mat

    delete[] buffer;

再次感谢您在我的问题上花费宝贵的时间

【问题讨论】:

你以二进制模式打开C流,为什么不以二进制模式打开C++流? ifstream depthStream("fileName.dat", std::ios_base::bin);(此外,每次迭代都删除和重新获取缓冲区似乎有点愚蠢,不是吗?并使用 std::vector 作为缓冲区。) 另见:***.com/questions/5605125/…。此外,您可能想使用 std::vector<char> buffer(size); 之类的东西,而不是 buffer = new char[size]; 这个:while(!depthStream.eof() 总是错的。除了文件结尾之外,其他情况可能会导致读取失败。 另请参阅Reading from text file until EOF repeats last line、How does ifstream's eof() work? 和所有相关帖子。 【参考方案1】:

您需要以二进制模式打开流,否则它将在它看到的第一个字节处停止,值为 26。

ifstream depthStream("fileName.dat", ios_base::in | ios_base::binary);

至于为什么 26 是特殊的,它是 Ctrl-Z 的代码,它是用于标记文本文件结尾的约定。这背后的历史记录在Raymond Chen's blog。

【讨论】:

等等,在第一个 26 字节处停止?我从来没有听说过这样的事情。我认为文本模式只是在 Windows 上将 \r\n 翻译成 \n,而在 linux/mac 上什么也没做。 my Google search 不会立即找到流和“26”之间的任何连接... @MooingDuck,例如见***.com/questions/15008907/… @MooingDuck - 这是微软的事情;文本文件中的 ctrl-Z 在其 C 库中被视为文件结尾。 刚刚花了 2 天时间试图弄清楚这里到底发生了什么......谢谢 Stack Overflow! 赞成,因为在过去的 3 个小时里我一直被这个问题困扰。从未听说过 26 如此特别。今天学到了一些很有趣的东西

以上是关于ifstream.eof() - 在真正结束之前到达文件末尾的主要内容,如果未能解决你的问题,请参考以下文章

五分钟后,你将真正理解MySQL事务隔离级别!

五分钟后,你将真正理解MySQL事务隔离级别!

js-函数柯里化

柯理化函数编程思想

ffmpeg在开始和结束之前将广告音频文件添加到原始音频文件[重复]

查找在 SQL Server 2014 中拥有多个帐户的客户的真正开始结束日期