10

I have a roughly 11.1G binary file where stores a series of the depth frames from the Kinect. There are 19437 frames in this file. To read one frame per time, I use ifstream in fstream but it reaches eof before the real end of the file. (I only got the first 20 frames, and the function stops because of the eof flag)

However, all frames can be read by using fread in stdio instead.

Can anyone explain this situation? Thank you for precious time on my question.

Here are my two functions:

// 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;
}

Again, thank you for precious time on my question

vonbrand
  • 10,026
  • 8
  • 27
  • 47
willSapgreen
  • 1,085
  • 2
  • 13
  • 24
  • 2
    you open the C stream in binary mode, why didn't you open the C++ stream in binary mode? `ifstream depthStream("fileName.dat", std::ios_base::bin);` (Also, deleting and reaquiring your buffer each iteration seems a little silly doesn't it? And use `std::vector` for the buffer.) – Mooing Duck Feb 22 '13 at 22:10
  • Also see: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong. In addition, you probably want to use something like `std::vector buffer(size);` instead of `buffer = new char[size];` – Jerry Coffin Feb 22 '13 at 22:17
  • This: `while(!depthStream.eof()` is always wrong. Other conditions can cause a read to fail aside from end of file. – Ed S. Feb 22 '13 at 23:25
  • Also see [Reading from text file until EOF repeats last line](https://stackoverflow.com/q/21647/608639), [How does ifstream's eof() work?](https://stackoverflow.com/q/4533063/608639) and all the related posts. – jww Jun 02 '17 at 19:46

1 Answers1

18

You need to open the stream in binary mode, otherwise it will stop at the first byte it sees with a value of 26.

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

As for why 26 is special, it's the code for Ctrl-Z which was a convention used to mark the end of a text file. The history behind this was recorded in Raymond Chen's blog.

Mark Ransom
  • 271,357
  • 39
  • 345
  • 578
  • wait, stop at the first byte with a 26? I've never heard of such a thing. I thought text mode merely translated `\r\n` into `\n` on windows, and did nothing on linux/mac. [my Google search](https://www.google.com/search?q=C%2B%2B%20stream%2026) doesn't immediately find any connection between streams and "26"... – Mooing Duck Feb 22 '13 at 22:12
  • 1
    @MooingDuck, see for example http://stackoverflow.com/questions/15008907/c-cin-fails-when-reading-more-than-127-ascii-values – Mark Ransom Feb 22 '13 at 22:14
  • 5
    @MooingDuck - this is a Microsoft thing; ctrl-Z in a text file is treated as end of file in their C library. – Pete Becker Feb 22 '13 at 22:42
  • Just spent 2 days trying to figure out what the hell was happening here... Thank you Stack Overflow! – MathematicalOrchid Nov 12 '13 at 13:08
  • 1
    Upvoted because I've been stuck on this problem for the past 3 hours. Never ever heard of 26 being so special. Learned something very interesting today – Alex Jan 02 '16 at 08:23