Reputation: 145
I'm trying to read a file block by block. Blocksize is 64Byte. But some bytes are left.
Example: I have a 360 Byte file and read the data in 64byte blocks, so I need 6 times a 64 byteblock to get all data.
typedef unsigned char uint1;
ifstream is(path.c_str(), ifstream::in | ifstream::binary);
uint1 data[64];
int i = 0;
while (is.read((char*)data, 64)) {
i++;
}
cout << i << endl;
But I only get 5 times a completely filled 64-Byte Block. How to get the remaining Bytes??
Upvotes: 2
Views: 2483
Reputation: 340
If your aim is actually to read the file, and not simply to count the number of blocks as your sample does then you probably want smth like this:
std::ifstream is( path.c_str(), std::ios_base::binary ); // in mode is always set for ifstream
if( !is )
throw std::runtime_error("unable to open file '" + path + "'" );
while( !is.eof() )
{
std::array< char, 64 > buf;
is.peek(); // needs this because of the buffering.
const auto n = is.readsome( buf.data(), buf.size() );
if( is )
handle_block( buf, n ); // std::cout.write( buf.data(), n )
else
throw std::runtime_error("error reading file '" + path + "'" );
}
Upvotes: 0
Reputation: 171127
360 is not divisible by 64, which means that the last block will not be read in its entirety. Consulting suitable documentation shows that reading such an incomplete block sets both eofbit
and failbit
on the stream from which you're reading, which means the condition in your while
loop will evaluate to false
for the last block. But the read did actually happen and the data is stored correctly.
You might want to check the value of gcount()
after the last read:
while (is.read((char*)data, 64)) {
i++;
}
if (is.gcount() > 0) {
i++;
}
Upvotes: 3
Reputation: 411
I suppose the problem is your file size is not divisible by buffer size, so last chunk's size is less than 64(360 - 64 * 5 = 40 bytes). And for this case doc for istream::read says:
If the input sequence runs out of characters to extract (i.e., the end-of-file is reached) before n characters have been successfully read, the array pointed to by s contains all the characters read until that point, and both the eofbit and failbit flags are set for the stream.
So, last is.read's return value is evaluated to "false" and it's not counted by your counter.
Upvotes: 4