fwrite/fread and unbuffered IO
Jeff Johnston
jjohnstn@redhat.com
Tue Sep 21 17:14:00 GMT 2004
Etienne Fortin wrote:
> Hi everyone,
> I'm playing with fread and fwrite and found some strange behaviors.
> Well, behavior that I wasn't expecting.
>
> If I put my FILE in "unbuffered mode" with setvbuf() and I call
> fwrite(), the memory pointer supplied to fwrite() is directly used as
> the source of the bytes being written to the stream. This is exactly
> what I expected since I'm unbuffered, ie no transit via some other
> buffer.
>
> But with fread, things are quite different. Let's say I'm unbuffered and
> I write something like this:
>
> fread(data, 1, 50, fp);
>
> I expect fread() to takes the "data" ptr directly as the container of
> the received bytes. But strangely, instead, fread() use the 1 bytes
> buffer embedded in the FILE structure (_ubuf) as a transit buffer for
> the received characters. This is absolutely not the behavior I expected.
> If I tell the FILE stream to be unbuffered, I don't expect my data to
> transit via some buffer, even if that buffer is as small as one byte.
> It's still a buffer. Also, this behavior is quite inneficient since the
> driver function responsible for getting characters from the stream is
> called the number of bytes needed, in the example 50 times!!! Unbuffered
> IO doesn't mean a device can't read bytes in sequence...
>
> Am I missing something here or is this behavior strange?
>
First of all the _ubuf is the ungetc buffer. Unbuffered I/O still has to read
characters from the ungetc buffer.
There is no restriction in ANSI that says how the library implements unbuffered
streams, only: " When a stream is unbuffered, characters are meant to appear
from the source or at the destination as soon as possible." However, that said,
you are correct in noting that the current design is inefficient for larger
reads and that if fread used the result buffer temporarily, one low-level read
could be used instead of multiple calls.
-- Jeff J.
More information about the Newlib
mailing list