2016-01-31 211 views
-1

我寫了下面的代碼將一個文件複製到另一個。雖然代碼有效,但代碼仍然會打印兩個錯誤消息。爲什麼是這樣 ?我是Unix和C編程的完全初學者(儘管我之前使用過C++),所以儘可能詳細的幫助將會非常棒。謝謝 !將一個文件複製到另一個文件(Unix/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); 
} 
+1

您重新打開這兩個文件與循環的每次迭代。 –

+0

*「代碼有效」*但您是否確實檢查過目標文件與源文件具有相同的內容?請用文件大小> 4096進行測試。 –

+0

您認爲在何處讀取新打開的文件開始?如果文件已經存在,'creat'e fucntion會做什麼? – Olaf

回答

3

您正在每次迭代中打開文件,並在每次迭代中嘗試creat文件。

所以除了第一次迭代之外,所有後續寫入都會失敗。它可能「似乎工作」,因爲你的輸入文件包含少於4096字節。因此,第一個寫作要求是讓所有東西都被複制。 如果使用超過4096字節的輸入,則只會看到前4096個字節(假設read()write()都不會失敗)。

如果write()要取得成功所有的時間(例如,你有外循環creat()),那麼open()呼叫持續打開相同的文件,並有潛在的無限循環或您的系統會用完文件描述符,並返回一個無效文件描述符和read()將會失敗。

長話短說:

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

另外,添加一些錯誤檢查。檢查fd(文件描述符)是否定的。文件路徑通過命令行可能無效。 – BryanT

+0

現在增加了錯誤檢查。謝謝。 –

2

以上回答已發現但對一個人應該:寫代碼一樣,:)

移動外循環兩種呼叫open()creat()不要使用creat(),因爲create()是一個過時的函數。 create(filename,mode);相當於 open(文件名,O_WRONLY | O_CREAT | O_TRUNC,模式);

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); 
} 
相關問題