1

When reading a file in chunks in C++, how do I handle the partial chunk at the end of the file? ifstream::read() only tells me that EOF was reached, there's no obvious way to tell how much it read before it hit EOF.

I.e I'm trying to port this C code to C++:

FILE * fp = fopen ("myfile.bin" , "rb");
char buffer[16 * 1024 * 1024];   // 16MB buffer
while (1) {
    int n = fread(buffer, 1, sizeof(buffer), fp);
    if (n < sizeof(buffer)) {
        // Couldn't read whole 16MB chunk;
        // process the last bit of the file.
        doSomething(buffer, n);
        break;
    }
    // Have a whole 16MB chunk; process it
    doSomething(buffer, sizeof(buffer));
}

Here's my start on a C++ version:

std::ifstream ifs("myfile.bin", std::ios::binary);
char buffer[16 * 1024 * 1024];   // 16MB buffer
while (1) {
    ifs.read(buffer, sizeof(buffer));
    if (ifs.eof()) {
        // help!!  Couldn't read whole 16MB chunk;
        // but how do I process the last bit of the file?
        doSomething(??????, ?????);
        break;
    }
    // Have a whole 16MB chunk; process it
    doSomething(buffer, sizeof(buffer));
}

I obviously could just compile the C code with a C++ compiler, but I'd rather use modern C++.

The only solution I could see was to read the file byte-by-byte - but the file is potentially several gigabytes, so "not being grossly inefficient" matters.

user9876
  • 10,954
  • 6
  • 44
  • 66

1 Answers1

1

The stream function gcount() is probably what you are looking for. The cppereference webpage has a perfect example. Here is how I would write your function:

std::ifstream ifs("myfile.bin", std::ios::binary);
char buffer[16 * 1024 * 1024];   // 16MB buffer
while (1) {
    ifs.read(buffer, sizeof(buffer));
    if (ifs.eof()) {
        // Couldn't read whole 16MB chunk;
        // Process as much as we could read:
        doSomething(buffer, ifs.gcount());
        break;
    }
    // Have a whole 16MB chunk; process it
    doSomething(buffer, sizeof(buffer));
}
user23573
  • 2,479
  • 1
  • 17
  • 36