Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the design of std::istream::read

std::istream has the prototype istream& read (char* s, streamsize n) the actual number of bytes read should be gotten by calling istream::gcount(), also the validity of the istream can be known from ios::good.

I was discussing another stream class' implementation I was trying to write with a colleague of mine, where I was saying I might follow this design; but he said instead of having the user call gcount everytime, one could have read's prototype like this istream& read (char* s, streamsize n, size_t &bytes_read) so that it'll get over in a single call and the former is clumsier. I was unable to defend std's design choice. What's the real rationale behind istream::read?

like image 515
legends2k Avatar asked Oct 07 '10 14:10

legends2k


2 Answers

I assume it's because C++ doesn't typically force an interface that may not be needed by everyone. If you require read to accept a parameter that some people don't care about, then it causes extra coding work (declaring an extra int to pass as a parameter). It also always saves the bytes read regardless of whether the client cares or not (some clients may just care that the read failed as indicated by the eof/fail bits).

With a separate method you de-couple the interface for different pieces of information that may or may not be needed.

like image 129
Mark B Avatar answered Oct 07 '22 05:10

Mark B


Try the readsome command instead,

streamsize readsome ( char* buf, streamsize num );

buf is your buffer and num is the number of bytes you wish to read, at most the number of bytes available in your buffer, of course.

The return value is the number of bytes actually read.

To read a file to the end you can loop:

char buf[BUF_SIZE]
streamsize bytesRead;
do
{
   bytesRead = instr.readsome( buf, BUF_SIZE );
   // do stuff with the bytes you read, if any
} while ( bytesRead == BUF_SIZE );
like image 30
CashCow Avatar answered Oct 07 '22 03:10

CashCow