3

Looking at the spec for fwrite(const void * ptr, size_t size, size_t count, FILE * stream), I'm unsure what exactly goes into the size parameter and the count parameter when writing binary data, i.e. a chunk of bytes.

Do I have to tell fwrite to write bufLen blocks of size 1, or should I tell it to write 1 block of size bufLen? Is any of these better? How does it affect the returned value? How does it affect the behaviour in the case of an error?
If I specify to write one block of size bufLen, does it always write either the complete data or nothing?

In code, it looks like this:

char* buf = ...;
int bufLen = ...;
FILE* file = ...;

/* alternative 1: */ int writtenByteCount = fwrite(buf, 1, bufLen, file);
/* alternative 2: */ int writtenByteCount = fwrite(buf, bufLen, 1, file);

printf("fwrite wrote %i of %i bytes/blocks", writtenByteCount, bufLen);

if (writtenByteCount < bufLen) {
    // handle error
}
Daniel S.
  • 6,458
  • 4
  • 35
  • 78
  • I think this might be a duplicate, because `fwrite()` usage must be extremely widespread, but I couldn't find this question on SO. – Daniel S. Jan 27 '14 at 11:17
  • 1
    `size: Size in bytes of each element to be written.` and `count: Number of elements, each one with a size of size bytes.` – Gasim Jan 27 '14 at 11:17
  • @Gasim, I already read that. It doesn't help me, because you can understand this in both ways. Is binary data one element of n bytes or is it n elements of length 1? – Daniel S. Jan 27 '14 at 11:19
  • @DanielS. Found an earlier thread. – Sebastian Redl Jan 27 '14 at 11:21
  • See related question http://stackoverflow.com/questions/13002367/write-a-file-byte-by-byte-in-c-using-fwrite and http://www.cplusplus.com/reference/cstdio/fwrite/ – Mihai8 Jan 27 '14 at 11:23
  • the count should be 1 logically because its the count, while size is size of each element. Just think of it this way. If you are writing some random class multiple times into a file, you should write the size as `sizeof(structNameHere)` and count as the number of times you want it. But result wise, i think they should both be the same because they are likely to multiply. – Gasim Jan 27 '14 at 11:24
  • if `fwrite` goes through a loop, trying to create each element separately, it will be unnecessarily long loop if you use count for the bytes. For example, if you have 1 object of size 4Mbs, I would want the loop to go once and then copy; instead of looping 4096 times and copy one byte on each iteration. – Gasim Jan 27 '14 at 11:30

1 Answers1

4

The fwrite() function shall write, from the array pointed to by ptr, up to nitems elements whose size is specified by size, to stream.

For each object( nitems times for a fwrite() call), size calls shall be made to the fputc(), taking the values (in order) from an array of unsigned char exactly overlaying the object.

As long as the underlying writes are buffered (which is commonly the case for most filesystems), the difference in performance of both the cases will be quite negligible.

The file-position indicator for the stream (if defined) shall be advanced by the number of bytes successfully written. If an error occurs, the resulting value of the file-position indicator for the stream is unspecified.


How the two variants differ is when partial writes are performed and fwrite() returns. Then having a smaller size and larger nitems provides a higher granularity in the return value.

For example if ONLY 5 bytes were written (in an attempt to write 10 bytes),

// case 1
fwrite(bufptr, 1, 10, fptr);
// returns 5. As 5 out of 10 items written successfully

// case 2
fwrite(bufptr, 10, 1, fptr);
// returns 0. As 0 out of 1 item written
TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130