简体   繁体   English

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

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

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. 我是Unix和C编程的完整入门者(尽管我以前使用过C ++),所以任何尽可能详尽的帮助都将是很棒的。 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);
}

You are opening the file in each iteration and attempt to creat the file in each iteration. 您将在每次迭代中打开文件,并尝试在每次迭代中creat文件。

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. 它可能“似乎起作用”,因为您的输入文件包含少于4096个字节。 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). 如果使用的输入超过4096个字节,则只会看到前4096个字节(假设read()write()都不会失败)。

If write() were to succeed all the time (eg 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. 如果write()一直都成功(例如,在循环外有creat() ),则open()调用将连续打开同一文件,并且可能是无限循环,否则系统将用尽文件描述符并返回无效的文件描述符和read()将对此失败。

Long story short: don't write code like that :) 长话短说: 不要写这样的代码:)

Move both calls to open() and creat() outside the loop: 将两个调用都移到循环外的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");
}

The above answer has spotted on however one should refrain from using creat(), as create() is an obsolete function. 上面的答案已经被发现,但是应该避免使用creat(),因为create()是一个过时的函数。 create(filename, mode); 创建(文件名,模式); is equivalent to open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode); 等效于open(filename,O_WRONLY | O_CREAT | O_TRUNC,mode);

http://www.gnu.org/software/libc/manual/html_node/Opening-and-Closing-Files.html 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);
}

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

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