使用缓冲区读取未知大小的文件

era*_*ros 6 c++ file-io buffer

我正在尝试从文件中读取块,但我遇到了问题.

char* inputBuffer = new char[blockSize]
while (inputFile.read(inputBuffer, blockSize)) {
    int i = inputFile.gcount();
//Do stuff
}
Run Code Online (Sandbox Code Playgroud)

假设我们的块大小是1024 bytes,文件是24,3 KiB.在阅读了第23个街区之后,将会有0,3 KiB阅读.我也想读一下0,3 KiB,实际上我gcount()稍后使用,所以我可以知道有多少缓冲区read(...)修改了(如果它更少).
但是当它访问第24个块时,read(...)返回一个值,使程序不进入循环,显然是因为文件中剩余未读字节的大小小于缓冲区大小.我该怎么办?

Bil*_*ter 3

我认为您在另一个答案的评论中谈到的康拉德·鲁道夫(Konrad Rudolf)对于阅读直到 eof 的问题提出了很好的观点。如果由于其他错误而永远无法达到 eof,那么您将陷入无限循环。因此,请采纳他的建议,但要修改它以解决您发现的问题。一种方法如下;

bool okay=true;
while ( okay ) {
    okay = inputFile.read(inputBuffer, blockSize);
    int i = inputFile.gcount();
    if( i ) {
        //Do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:由于我的答案已被接受,我正在编辑它以使其尽可能有用。事实证明我的 bool OK 是完全没有必要的(参见ferosekhanj 的回答)。最好直接测试 inputFile 的值,这还有一个优点,如果文件未正确打开,您可以优雅地避免进入循环。所以我认为这是这个问题的规范解决方案;

inputFile.open( "test.txt", ios::binary );
while ( inputFile ) {
    inputFile.read( inputBuffer, blockSize );
    int i = inputFile.gcount();
    if( i ) {
        //Do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,最后一次 //Do stuff 时,i 将小于 blockSize,除非文件恰好是 blockSize 字节长的倍数。

Konrad Rudolf在这里的回答也很好,它的优点是.gcount()只在循环之外调用一次,但缺点是它确实需要将数据处理放在单独的函数中,以避免重复。