Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the main differences between fwrite and write?

Tags:

c++

c

I'm currently writing a callback function in C:

static size_t writedata(void *ptr, size_t size, size_t nmemb, void *stream){

        size_t written = fwrite(ptr, size, nmemb, (FILE)*stream);
        return written;
}

This function is going to be used in another function, which does a HTTP request, retrieves the request, and writes it to the local machine. That writedata function will be used for the later part. The whole operation has to be multithreaded, so I was in doubt between write and fwrite. Could someone help me outlining the differences between write() and fwrite() in C, so I could choose which one best fits into my problem?

like image 951
cybertextron Avatar asked Jul 10 '12 13:07

cybertextron


People also ask

What is the difference between fwrite and fprintf?

fprintf writes a string. fwrite writes bytes.

What is the difference between fwrite () and File_put_contents ()?

fwrite() allows to write to file a byte or block of bytes at a time, file_put_content() writes the entire file in one go.... which is better? depends what you need to do! and on the volumes of data that you want to write! fwrite requires a handle while file_put_contents does not.

Is fwrite faster than write?

Takeaway: The write function is a call to the operating system made by your application, it is slower than fwrite().

Does fwrite call write?

In other words, fwrite(3) is just a library routine that collects up output into chunks, and then calls write(2) .


2 Answers

fwrite writes to a FILE*, i.e. a (potentially) buffered stdio stream. It's specified by the ISO C standard. Additionally, on POSIX systems, fwrite is thread-safe to a certain degree.

write is a lower-level API based on file descriptors, described in the POSIX standard. It doesn't know about buffering. If you want to use it on a FILE*, then fetch its file descriptor with fileno, but be sure to manually lock and flush the stream before attempting a write.

Use fwrite unless you know what you're doing.

like image 167
Fred Foo Avatar answered Sep 22 '22 00:09

Fred Foo


One very noticeable difference is write is atomic and fwrite isn't.

https://yarchive.net/comp/linux/wakekill.html

Using:

#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 =
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n";
    for (int i = 0; i < 10000; 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 < 10000; 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;
}

You will get output like this, no interleaving lines:

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

Using:

#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 =
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n";
    for (int i = 0; i < 10000; 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 < 10000; 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;
}

You will get output like this, interleaving lines:

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
like image 42
ericcurtin Avatar answered Sep 23 '22 00:09

ericcurtin