Reputation: 612
I am trying to achieve something like this:
while (ifstream has not been entirely read)
{
read a chunk of data into a buffer that has size BUFLEN
write this buffer to ostream
}
At first I tried to achieve this by using ifstream.eof()
as my while condition, but I've heard that this is not the way to go. I've been looking at std::ios::ifstream's other functions, but can't figure out what else to use.
PS: I am using a buffer because the file that is being transferred can get very big.
Upvotes: 5
Views: 5712
Reputation: 409166
The istream::read
function returns the stream, which can be used as a boolean expression, so you can do something like:
while (is.read(buffer, BUFLEN))
{
outputfile.write(buffer, is.gcount());
}
if (is.eof())
{
if (is.gcount() > 0)
{
// Still a few bytes left to write
outputfile.write(buffer, is.gcount());
}
}
else if (is.bad())
{
// Error reading
}
You might want to check that the write inside the loop doesn't fail too.
Upvotes: 6
Reputation: 153909
The iostream classes take care of all necessary buffering, so you don't have to. The usual idiom to copy an entire file is just:
fout << fin.rdbuf();
iostream takes care of all of the necessary buffering. (This is a
somewhat unusual use of <<
, since it doesn't format. Historical
reasons, no doubt.)
If you need the loop, perhaps because you want to do some
transformations on the data before rewriting it, then it's a little
tricker, since istream::read
“fails” unless it reads the
requested number of characters. Because of this, you have to also check
how many characters were read, and process them even if the read failed:
int readCount;
while ( fin.read( &buf[0], buf.size() )
|| (readCount = fin.gcount()) != 0 ) {
// ...
fout.write( &buf[0], readCount );
}
This is fairly ugly; a better solution might be to wrap the buffer in a
class, and define an operator<<
for this class.
Upvotes: 7
Reputation: 399803
Your logic is simply wrong.
You need to go about it more like this:
while (a chunk larger than zero could be read)
{
write chunk to output
}
See how that is even simpler? There's no need to explicitly check for "end of file", just read data until you fail. Then you're done.
Upvotes: 0