繁体   English   中英

将一个文件复制到另一个文件(Unix / C)?

[英]Copying one file to another(Unix/C)?

我编写了以下代码,将一个文件复制到另一个文件。 尽管该代码可以工作,但是该代码仍会同时打印两条错误消息。 为什么是这样 ? 我是Unix和C编程的完整入门者(尽管我以前使用过C ++),所以任何尽可能详尽的帮助都将是很棒的。 谢谢 !

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);
}

您将在每次迭代中打开文件,并尝试在每次迭代中creat文件。

因此,除了第一次迭代外,所有后续写入都将失败。 它可能“似乎起作用”,因为您的输入文件包含少于4096个字节。 因此,第一个写入请求是使它看起来像所有内容都已被复制。 如果使用的输入超过4096个字节,则只会看到前4096个字节(假设read()write()都不会失败)。

如果write()一直都成功(例如,在循环外有creat() ),则open()调用将连续打开同一文件,并且可能是无限循环,否则系统将用尽文件描述符并返回无效的文件描述符和read()将对此失败。

长话短说: 不要写这样的代码:)

将两个调用都移到循环外的open()creat()

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");
}

上面的答案已经被发现,但是应该避免使用creat(),因为create()是一个过时的函数。 创建(文件名,模式); 等效于open(filename,O_WRONLY | O_CREAT | O_TRUNC,mode);

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

最好将代码编写为:

#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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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