Overview:
C has two sets of binary stream files for reading and writing in UNIX: fread() and fwrite(). fwrite() is a function that writes to a FILE*, which is a (possibly) buffered stdio stream. The ISO C standard specifies it. Furthermore, fwrite() is thread-safe to a degree on POSIX platforms. The POSIX standard defines write as a lower-level API based on file descriptors. It is unaware of the concept of buffering. If you wish to use it on a FILE*, use file to get its file descriptor, but lock and flush the stream manually before performing to write. Unless you’re sure what you’re doing, use fwrite().
Note –
One thing to keep in mind is that accessing a FILE* structure from multiple threads (which includes, but is not limited to, executing fread/fwrite) is often riskier than doing so with low-level file descriptors.
Takeaway:
- The write function is a call to the operating system made by your application, it is slower than fwrite().
- It also lacks buffering, which makes it considerably sluggish because, as the buffering theory implies, “it is faster to process several tiny files than a large one.”
- It’s also worth noting that write isn’t part of the C standard, thus you won’t find it on non-POSIX systems, and the appropriate use may change (rarely).
- It’s also worth noting that write and read are sometimes used to implement fwrite() and fread() (a simple implementation can be found in the chapter about Unix of K&R).
- One more distinction between write and fwrite is that write is atomic whereas fwrite is not.
Example –
Consider the following Code Sample as follows.
Sample code-1:
C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
FILE * h = fopen ( "file.txt" , "a" );
char * line =
"gggggggggggggggggggggggggggggggggggggggggggggggg\n" ;
for ( int i = 0; i < 1000; i++) {
if (write(fileno(h), line, strlen (line)) != strlen (line)) {
perror ( "Could not append line to file" );
exit (1);
}
}
if ( fclose (h) != 0) {
perror ( "Could not close file" );
exit (1);
}
} else {
FILE * h = fopen ( "file.txt" , "a" );
char * line =
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" ;
for ( int i = 0; i < 1000; i++) {
if (write(fileno(h), line, strlen (line)) != strlen (line)) {
perror ( "Could not append line to file" );
exit (1);
}
}
if ( fclose (h) != 0) {
perror ( "Could not close file" );
exit (1);
}
}
return 0;
}
|
Output :
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
gggggggggggggggggggggggggggggggggggggggggggggggg
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
gggggggggggggggggggggggggggggggggggggggggggggggg
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
gggggggggggggggggggggggggggggggggggggggggggggggg
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
gggggggggggggggggggggggggggggggggggggggggggggggg
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
Sample code-2:
As you may see, there are no interleaving lines in the output Now, consider this sample code as follows.
C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
FILE * h = fopen ( "file.txt" , "a" );
char * line =
"gggggggggggggggggggggggggggggggggggggggggggggggg\n" ;
for ( int i = 0; i < 1000; i++) {
if ( fwrite (line, 1, strlen (line), h) != strlen (line)) {
perror ( "Could not append line to file" );
exit (1);
}
}
if ( fclose (h) != 0) {
perror ( "Could not close file" );
exit (1);
}
} else {
FILE * h = fopen ( "file.txt" , "a" );
char * line =
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" ;
for ( int i = 0; i < 1000; i++) {
if ( fwrite (line, 1, strlen (line), h) != strlen (line)) {
perror ( "Could not append line to file" );
exit (1);
}
}
if ( fclose (h) != 0) {
perror ( "Could not close file" );
exit (1);
}
}
return 0;
}
|
Output :
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggg
ggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggg
Difference between fwrite() and write():
Feature |
fwrite() |
write() |
Purpose |
Write to a FILE stream |
Write to a file descriptor |
Buffering |
Buffered I/O |
Unbuffered I/O |
Standard |
Part of C standard |
Not part of C standard, POSIX-specific |
Thread-safety |
Thread-safe |
Thread-safe |
Implementation detail |
Uses write() internally |
Lower-level than fwrite() |
Atomicity |
Not atomic |
Atomic |
Performance |
Slower |
Faster |
Error handling |
Returns error status |
Returns -1 on error |
Conclusion :
Here comes the interviewing lines into play, hence stipulating the latter to be non-atomic and the former to be atomic. Hope this clears away the ever slightest difference between fwrite() & write(). The Difference is small, only key factors change!
Last Updated :
05 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...