简体   繁体   中英

How to not write more bytes than are in the buffer in C?

I'm trying to write a simple copy program. It reads test_data.txt in chunks of 100 bytes and copies those bytes to test_dest.txt . I find that the destination file is at least one unit of chunk larger than the source file. How could I adjust it so that just the right number of bytes are copied? Would I need a copy buffer of size 1? Please not the point is to solve it using low level I/O system calls.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main() { 

    int fh  = open("test_data.txt", O_RDONLY);
    int trg = open("test_dest.txt", O_CREAT | O_WRONLY);

    int  BUF_SIZE = 100;
    char inp[BUF_SIZE]; 

    int read_bytes = read(fh, inp, BUF_SIZE);
    while (read_bytes > 0) {
        write(trg, inp, BUF_SIZE);
        read_bytes = read(fh, inp, BUF_SIZE);
    }   

    close(trg);
    close(fh);
    return 0;
}

The read function just told you how many bytes it read. You should write that amount of bytes:

write(trg, inp, read_bytes);

On another note, you really should check for failures from the write call as well. And definitely the open calls.

On yet another note, you only really need one call to read :

ssize_t read_bytes;  // The read function is specified by POSIX to return a ssize_t
while ((read_bytes = read(fh, inp, sizeof inp)) > 0)
{
    write(trg, inp, read_bytes);
}

Your code is not standard C11. Check by reading the standard n1570 , and read before the Modern C book.

Your code is more or less POSIX , and certainly compiles on most Linux distributions, eg Debian or Ubuntu (you want to install their build-essentials metapackage).

Please read the documentation of open(2 ), read(2) , write(2) , every syscalls(2) you are using, and of errno(3) .

Notice that each of the functions you are calling can fail, and your code should test for the failure case . Also be aware that a write (or a read ) could be partial in some cases, and this is documented.

Recommendation:

with a recent GCC -the usual C compiler on most Linux distributions, compile with all warnings and debug info, so gcc -Wall -Wextra -g .

Read Advanced Linux Programming andHow to debug small programs

Learn to use the GDB debugger .

Read about build automation tools, such as GNU make (a very common tool on most Linux systems) or ninja .

Be aware of strace(1) . You might use it on cp(1) , or study the source code of GNU coreutils (providing cp ).

Remember that most Linux distributions are mostly made of open source software .

You are allowed to study their source code.

I even believe that you should study their source code , at least for inspiration !

I'm trying to write a simple copy program. It reads test_data.txt in chunks of 100 bytes and copies those bytes to test_dest.txt

If performance matters, the chunk size of 100 bytes is really too small in practice. I would recommend a power of two bigger than 4Kbytes (the usual page size on x86-64).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM