This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: fwrite/fread and unbuffered IO


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]