Copying one file to another(Unix/C)?

这一生的挚爱 提交于 2019-12-14 04:12:05

问题


I have written the following code to copy one file to another. Although the code works, the code still prints both error messages. Why is this ? I am a complete beginner to Unix and C programming(although I have worked with C++ before), so any help in as much detail as possible would be great. Thanks !

int main(int argc, char *argv[])
{
    int n;
    char buf[4096];
    while ((n=read( open(argv[1], O_RDONLY) , buf, 4096))>0)
    {
        if (write(creat(argv[2], S_IREAD | S_IWRITE ), buf, n)!=n)
            printf("Error writing to file.\n");
    }
    if (n<0)
        printf("Error reading from file.\n");
    exit(0);
}

回答1:


You are opening the file in each iteration and attempt to creat the file in each iteration.

So except the very first iteration, all subsequent writes will fail. It probably "seems to work" because your input file contains less than 4096 bytes. So the first call to write was to make it look like everything was copied. If use an input which has more than 4096 bytes, you'll see only the first 4096 bytes (assuming both read() and write() don't fail).

If write() were to succeed all the time (e.g. you had the creat() outside the loop) then the open() call continuously opens the same file and is potentially an infinite loop or your system would run out of file descriptor and return an invalid file descriptor and read() will fail on that.

Long story short: don't write code like that :)

Move both calls to open() and creat() outside the loop:

int fd = open(argv[1], O_RDONLY);
if (fd == -1) { 
   perror("open");
   exit(1);
}

int fd2 = creat(argv[2], S_IREAD | S_IWRITE );
if (fd2 == -1) { 
   perror("write");
   exit(1);
}

while ( (n=read( fd , buf, 4096)) > 0 )
{
    if ( write(fd2 , buf, n) != n )
        printf("Error writing to file.\n");
}



回答2:


The above answer has spotted on however one should refrain from using creat(), as create() is an obsolete function. create(filename, mode); is equivalent to open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);

http://www.gnu.org/software/libc/manual/html_node/Opening-and-Closing-Files.html

The code could be better written as:

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

#define BUFSIZE 4096

int main(int argc, char **argv)
{
    int infd, outfd;
    int n;
    char *infile = NULL;
    char *outfile = NULL;
    int src_flags, dest_flags;
    mode_t dest_perms;
    char buf[BUFSIZE];

    if (argc < 3) {
        fprintf(stderr, "At least src and dest files must be specified\n"); /*Never rely on users' inputs*/
        /*Print usage information if possible*/
        exit(EXIT_FAILURE); 
    }

    infile = argv[1];
    outfile = argv[2];  /*Presuming the order*/            

    src_flags = O_RDONLY;
    dest_flags = O_CREAT | O_WRONLY | O_TRUNC;  
    /*creat() is equivalent to open(fname, O_CREAT | O_WRONLY | O_TRUNC, mode)*/
    dest_perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /*rw-rw-rw-*/

    infd = open(infile, src_flags);
    if (infd == -1) {
        perror("cannot open src ");
        exit(EXIT_FAILURE);
    }

    outfd = open(outfile, dest_flags, dest_perms);
    if (outfd == -1) {
        perror("cannot open dest ");
        exit(EXIT_FAILURE);
    }

    while ((n = read(infd, buf, BUFSIZE)) > 0) {
        if (write(outfd, buf, n) != n) {
            fprintf(stderr, "failed to write buf\n");
            goto exit_failure;
        }
    }

    if (n == -1) {
        fprintf(stderr, "read() failed\n");
        goto exit_failure;
    }

exit_failure:
     if (infd) {
        close(infd);
     }

    if (outfd) {
        close(outfd);
    }

    printf("Copy successful\n");

    exit(EXIT_SUCCESS);
}


来源:https://stackoverflow.com/questions/35119938/copying-one-file-to-anotherunix-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!