我正在尝试从文件中读取块,但我遇到了问题。
char* inputBuffer = new char[blockSize]
while (inputFile.read(inputBuffer, blockSize)) {
int i = inputFile.gcount();
//Do stuff
}
假设我们的块大小为1024 bytes
,文件为24,3 KiB
。阅读第23个区块后,将会有0,3 KiB
个阅读。我还想阅读0,3 KiB
,事实上我稍后使用gcount()
因此我可以知道有多少缓冲区read(...)
修改了(如果它更少)。
但是当它访问第24个块时,read(...)
返回一个值,使程序不进入循环,显然是因为文件中剩余未读字节的大小小于缓冲区大小。我该怎么办?
答案 0 :(得分:3)
我认为你在另一个答案的评论中谈到的康拉德鲁道夫(Konrad Rudolf)对阅读问题提出了一个很好的观点。如果由于某些其他错误而永远不会达到eof,那么您将处于无限循环中。所以请听取他的意见,但要对其进行修改以解决您发现的问题。一种方法如下;
bool okay=true;
while ( okay ) {
okay = inputFile.read(inputBuffer, blockSize);
int i = inputFile.gcount();
if( i ) {
//Do stuff
}
}
编辑:由于我的答案已被接受,我正在编辑它以尽可能有用。事实证明我的bool没关系是完全没必要的(参见ferosekhanj的回答)。最好直接测试inputFile的值,还有一个优点,即如果文件没有打开就可以优雅地避免进入循环。所以我认为这是解决这个问题的规范解决方案;
inputFile.open( "test.txt", ios::binary );
while ( inputFile ) {
inputFile.read( inputBuffer, blockSize );
int i = inputFile.gcount();
if( i ) {
//Do stuff
}
}
现在你最后一次//做东西,我会比blockSize小,除非文件恰好是blockSize字节长的倍数。
Konrad Rudolf的回答here也很好,它的优点是.gcount()只在循环外调用一次,但缺点是它确实需要将数据处理放在一个单独的函数中,避免重复。答案 1 :(得分:3)
@Konrad Rudolph提到的解决方案是检查流对象本身,因为这包括检查eof和错误条件。 inputFile.read()返回inputFile本身的流,因此您可以像
一样编写while(inputFile.read())
但这总是不起作用。它失败的情况就是你的情况。一个合适的解决方案就是写下面的
char* inputBuffer = new char[blockSize]
while (inputFile)
{
inputFile.read(inputBuffer, blockSize);
int count = inputFile.gcount();
//Access the buffer until count bytes
//Do stuff
}
我认为这是@Konrad Rudolph在帖子中所说的解决方案。根据我以前的CPP经验,我也会做类似的事情。
答案 2 :(得分:1)
但是当它访问第24个块时,read(...)返回一个值,使程序不进入循环,显然是因为文件中剩余未读字节的大小小于缓冲区大小。 / p>
那是因为你的循环错了。你应该这样做:
while(!inputFile) {
std::streamsize numBytes = inputFile.readsome(inputBuffer, blockSize);
//Do stuff
}
请注意使用readsome
代替read
。