Open In App

fwrite() Vs write()

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. The write function is a call to the operating system made by your application, it is slower than fwrite().
  2. 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.”
  3. 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).
  4. 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).
  5. 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) {
     
    // open file for append
    //Checking if fork is really 0
    FILE* h = fopen("file.txt", "a");
     
    // line is a pointer which is of char type
    char* line =
        "gggggggggggggggggggggggggggggggggggggggggggggggg\n";
     
    // logic if condition not match
    // then line will not be append to file.
    //Looping till the condition of printing is not fulfilled!
    for (int i = 0; i < 1000; i++) {
      if (write(fileno(h), line, strlen(line)) != strlen(line)) {
        perror("Could not append line to file");
        //There was some error, this is exception handling
        exit(1);
      }
    }
     
    // close file on the basis of condition
    if (fclose(h) != 0) {
      perror("Could not close file");
      exit(1);
    }
  } else {
    //Opening and Writing on a Text File
    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");
      //Exception Handling if file could not be closed
      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() {
   
  //Checking the fork condition again
  if (fork() == 0) {
    FILE* h = fopen("file.txt", "a");
    //Creating a char line, similar to the code above
    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");
        //Exception Handling
        exit(1);
      }
    }
    if (fclose(h) != 0) {
      perror("Could not close file");
      //File could not be closed
      exit(1);
    }
  } else {
    //Opening the file again
    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");
        //Exception Handling
        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
Previous
Next
Share your thoughts in the comments
Similar Reads