In the POSIX API, read()
returns 0 to indicate that the end-of-file has been reached. Why isn't there a separate function that tells you that read()
would return zero -- without requiring you to actually call read()
?
Reason for asking: Since you have to call read()
in order to discover that it will fail, this makes file reading algorithms more complicated and maybe slightly less efficient since they have to allocate a target buffer that may not be needed.
What we might like to do...
while ( !eof )
{
allocate buffer
read to buffer
process buffer
}
What we have to do instead...
while ( true )
{
allocate buffer
read to buffer
if ( eof ) release buffer, break;
process buffer
}
Additionally, it seems like this behavior propagates itself into higher-level APIs such as fread()
and feof()
in C -- and creates a lot of confusion about how to use feof()
correctly:
To gain perspective on why this might be the case, understand that end-of-stream is not inherently a permanent situation. A file's read pointer could be at the end, but if more data is subsequently appended by a write operation, then subsequent reads will succeed.
Example: In Linux, when reading from the console, a new line followed by
^D
will causeposix::read()
to return zero (indicating "end of file"). However, if the program isn't terminated, the program can continue to read (assuming additional lines are typed).Since end-of-stream is not a permanent situation, perhaps it makes sense to not even have an is_at_end() function (POSIX does not). Unfortunately, this does put some additional burden on the programmer (and/or a wrapper library) to elegantly and efficiently deal with this complexity.