Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does fread really work?

Tags:

c

fread

The declaration of fread is as following:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 

The question is: Is there a difference in reading performance of two such calls to fread:

char a[1000]; 
  1. fread(a, 1, 1000, stdin);
  2. fread(a, 1000, 1, stdin);

Will it read 1000 bytes at once each time?

like image 926
Roman Byshko Avatar asked Dec 21 '11 11:12

Roman Byshko


People also ask

What does fread do all day?

The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.

Can fread fail?

If fread fails, it will typically keep failing. Typically because it hit the end of file, but possibly for some other reason. If it fails, you would normally not try again.

Does fread call read?

It makes a direct system call on UNIX. fread() is part of the C library, and provides buffered reads. It is usually implemented by calling read() in order to fill its buffer.

What does fread () return in C?

fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count . Use the feof or ferror function to distinguish a read error from an end-of-file condition.


1 Answers

There may or may not be any difference in performance. There is a difference in semantics.

fread(a, 1, 1000, stdin); 

attempts to read 1000 data elements, each of which is 1 byte long.

fread(a, 1000, 1, stdin); 

attempts to read 1 data element which is 1000 bytes long.

They're different because fread() returns the number of data elements it was able to read, not the number of bytes. If it reaches end-of-file (or an error condition) before reading the full 1000 bytes, the first version has to indicate exactly how many bytes it read; the second just fails and returns 0.

In practice, it's probably just going to call a lower-level function that attempts to read 1000 bytes and indicates how many bytes it actually read. For larger reads, it might make multiple lower-level calls. The computation of the value to be returned by fread() is different, but the expense of the calculation is trivial.

There may be a difference if the implementation can tell, before attempting to read the data, that there isn't enough data to read. For example, if you're reading from a 900-byte file, the first version will read all 900 bytes and return 900, while the second might not bother to read anything. In both cases, the file position indicator is advanced by the number of characters successfully read, i.e., 900.

But in general, you should probably choose how to call it based on what information you need from it. Read a single data element if a partial read is no better than not reading anything at all. Read in smaller chunks if partial reads are useful.

like image 145
Keith Thompson Avatar answered Sep 21 '22 05:09

Keith Thompson