簡體   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