is std::ifstream buffered or not?

K

Karl

Hey everyone!

I've got a quick question on whether std::ifstream is buffered or not.
The reason is that I have a homework assignment that requires me to
benchmark copying files using different buffer sizes. I ended up doing
this using std::istream::readsome() and std::eek:stream::write():

// now try writing to the destination file
std::ifstream sourceStream(sourceFilename.c_str(),
std::ios::binary);
std::eek:fstream destinationStream(destinationFilename.c_str(),
std::ios::binary | std::ios::trunc);

// determine the size of the file
sourceStream.seekg(0, std::ios::end);
const std::streamsize totalLength = sourceStream.tellg();
sourceStream.seekg(0, std::ios::beg);

// now writing the actual data
char buffer[numberOfBytes];
std::streamsize length = 0;
while(length != totalLength)
{
int l = sourceStream.readsome(buffer, numberOfBytes);
destinationStream.write(buffer, l);
length += l;
}
// now close the stream
sourceStream.close();
destinationStream.close();

Now, the validity of benchmarking this could possibly be in question
because std::istream::readsome() could be doing some buffering
(readahead?) in the back, so using different buffer sizes would
possibly be meaningless.

I understand std::cout and std::cin is buffered, and it makes sense
that they are. However, I do not see why std::ifstream and
std::eek:fstream would be buffered because the filesystem and even the
harddrive does some buffering. Wouldn't that be meaningless?

Then again, this could depend on the implementation. I'm not familiar
enough with the C++ STL specification.

Can anyone help me out? Any help would be greatly appreciated. :)
 
T

Tom Widmer

Karl said:
Hey everyone!

I've got a quick question on whether std::ifstream is buffered or not.

It is, typically.
The reason is that I have a homework assignment that requires me to
benchmark copying files using different buffer sizes. I ended up doing
this using std::istream::readsome() and std::eek:stream::write():

// now try writing to the destination file
std::ifstream sourceStream(sourceFilename.c_str(),
std::ios::binary);
std::eek:fstream destinationStream(destinationFilename.c_str(),
std::ios::binary | std::ios::trunc);

// determine the size of the file
sourceStream.seekg(0, std::ios::end);
const std::streamsize totalLength = sourceStream.tellg();
sourceStream.seekg(0, std::ios::beg);

// now writing the actual data
char buffer[numberOfBytes];
std::streamsize length = 0;
while(length != totalLength)
{
int l = sourceStream.readsome(buffer, numberOfBytes);
destinationStream.write(buffer, l);
length += l;
}
// now close the stream
sourceStream.close();
destinationStream.close();

Now, the validity of benchmarking this could possibly be in question
because std::istream::readsome() could be doing some buffering
(readahead?) in the back, so using different buffer sizes would
possibly be meaningless.

I understand std::cout and std::cin is buffered, and it makes sense
that they are. However, I do not see why std::ifstream and
std::eek:fstream would be buffered because the filesystem and even the
harddrive does some buffering. Wouldn't that be meaningless?

Not at all. Buffering is useful at many levels. For iostreams, buffering
is done to reduce the number of virtual function calls made, and to
reduce the number of OS read calls made, both of which improve
performance regardless of any buffering happening at lower levels.
Then again, this could depend on the implementation. I'm not familiar
enough with the C++ STL specification.

Can anyone help me out? Any help would be greatly appreciated. :)

You can disable iostream level buffering like this:
std::ifstream sourceStream;
sourceStream.rdbuf()->pubsetbuf(0, 0);
sourceStream.open(sourceFilename.c_str(), std::ios::binary);

std::eek:fstream destinationStream;
destinationStream.rdbuf()->pubsetbuf(0, 0);
destinationStream.open(destinationFilename.c_str(),
std::ios::binary | std::ios::trunc);

Note for it to be sure to work, you need to set up the buffer before
opening the file.

Tom
 
K

Karl

Tom said:
You can disable iostream level buffering like this:
std::ifstream sourceStream;
sourceStream.rdbuf()->pubsetbuf(0, 0);
sourceStream.open(sourceFilename.c_str(), std::ios::binary);

std::eek:fstream destinationStream;
destinationStream.rdbuf()->pubsetbuf(0, 0);
destinationStream.open(destinationFilename.c_str(),
std::ios::binary | std::ios::trunc);

Note for it to be sure to work, you need to set up the buffer before
opening the file.

Thank you Tom, that's perfect! I looked at the pubsetbuf()
documentation and see that that does exactly what I need. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top