Search code examples
clinuxfilesystemstdio

How to use read and write past BUFSIZ in C


For an assignment, I'm supposed to create two methods: Method one will read() and write() the input file to an empty output file, one byte at a time (slowly).

The other method will instead use char buf[BUFSIZ]; where BUFSIZ is from <stdio.h>. We are supposed to read() and write() with the BUFSIZ which will make things a lot faster.

The input file we test each method on is just a linux dictionary (/dict/linux.words).

I've correctly implemented method one, where I call read() and write() on one character at a time, copying the input file to the output file. Although it's very slow, it at least copies everything over.

My code for this looks like this:

// assume we have a valid, opened fd_in and fd_out file.
char buf;
while(read(fd_in, buf, 1) != 0)
    write(fd_out, buf, 1);

For method two however, where I use BUFSIZ, I am not able to transfer every single entry into the output file. It fails in the z entries, and doesn't write anymore.

So, my first try:

// assume we have a valid, opened fd_in and fd_out file
char buf[BUFSIZ];
while(read(fd_in, buf, BUFSIZ) != 0)
    write(fd_out, buf, BUFSIZ);

doesn't work.

I understand that read() will return either the number of bytes read or 0 if it is at the end of a file. The problem I'm having is understanding how I can compare read() to BUFSIZ, and then loop around and start read() at where it left off until I reach the real end of file.


Solution

  • Since your file will most likely not be an exact multiple of BUFSIZ you need to check for the actual number of bytes read, so that the last block will be written correctly, e.g.

    char buf[BUFSIZ];
    ssize_t n;
    while((n = read(fd_in, buf, BUFSIZ)) > 0)
        write(fd_out, buf, n);