what are the main differences between fwrite and write?

前端 未结 3 2034
天涯浪人
天涯浪人 2020-12-29 11:05

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 wr         


        
相关标签:
3条回答
  • 2020-12-29 11:15

    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.

    0 讨论(0)
  • 2020-12-29 11:17

    The write function is a call that your program makes to the operating system and therefore it is slower than fwrite. It also lacks of buffering which makes it even slower because as the philosophy of buffering suggests: "It is faster to handle many portions of small files rather than a big one." It is also important that write is not part of the c standard, so you probably won't find it non-POSIX systems and (rarely) the apropriate use will differ. You should also known that fwrite and fread are some times implemented using write and read (a simple implementation can be found in the chapter about Unix of K&R).

    Another noteable thing is that read and write use file descriptors, but fread and fwrite use the FILE pointers which are actually pointers which contain file descriptors and other info about the file opened.

    0 讨论(0)
  • 2020-12-29 11:29

    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
    
    0 讨论(0)
提交回复
热议问题