2013-10-18 67 views
1

這是創建一個文件或目錄的副本,使用Fedora 19中的gcc編譯的ac代碼。它運行但不停止,我可以看到新創建的文件保持不變可笑地增加大小。這段代碼有什麼問題?如何防止無限循環寫入文件

#include<fcntl.h> 
#include<stdio.h> 
#include<unistd.h> 

char buffer[2048]; 

int version = 1; 

int main(int argc, char *argv[]) 
{ 
    void copy (int, int); 

    int fdold, fdnew; 

    if (argc != 3) 
    { 
     printf("insufficient arguments !!! \n"); 
     return (1); 
    } 

    fdold = open(argv[1], O_RDONLY); 
    if (fdold == -1) 
    { 
     printf("cannot open file %s\n",argv[1]); 
     return (1); 
    } 

    fdnew = creat(argv[2],0666); 
    if (fdnew == -1) 
    { 
     printf("cannot create file %s\n",argv[2]); 
     return (1); 
    } 

    copy (fdold, fdnew) 

    return (0); 
} 

void copy (int fdold, int fdnew) 
{ 
    int count; 
    count = read(fdold, buffer, sizeof(buffer)); 

    while (count > 0) 
     write(fdnew, buffer, count); 
} 
+3

這一段時間(數)循環是要很長一段很長一段時間運行。 –

回答

5

你永遠不更新count和你保持一遍又一遍寫相同的數據。在此代碼:

count = read(fdold, buffer, sizeof(buffer)); 
while (count > 0) 
    write(fdnew, buffer, count); 

您從文件描述符讀取一次,在count字節拉動,雖然它大於0(這大概是),你把寫緩衝區輸出到新的文件。你永遠不會從舊文件中讀取更多數據。如果您可以看到文件變得越來越大,您可能也會看到(取決於內容如何刷新到磁盤)相同的內容重複一遍又一遍。

你真正需要做的是更多的東西是這樣的:

while there is data to read from the old file 
    read it into a buffer 
    while there is data in the buffer to write to the new file 
    write data from the buffer into the new file 

在略低於僞codish,但高度未經測試的形式,我想你會尋找排序的是這樣的:

int count = 0; 
int written; 
while (0 < (count = read(fdold, buffer, sizeof(buffer)))) { 
    written = 0; 
    while (count > (written += write(fdnew, buffer+written, count-written)))); 
} 

外環可以確保您閱讀,直到有沒有什麼可以閱讀,以及內,同時確保您撥打write直到written大如count,也就是說,直到你寫的所有字節你讀過的。這是「聰明」的代碼,但它實際上太聰明瞭;你實際上需要檢查written是否爲-1,否則你會開始做一些奇怪的事情。

東西與更多的錯誤檢查,並希望更地道,可能是:

for (int count_in = -1; count_in != 0;) { 
    if (-1 == (count_in = read(fd, buf, bufsize))) { 
     perror("Problem reading from file"); 
     exit(-1); 
    } 
    else { 
     for (int count_out = 0, out = 0; count_out < count_in; count_out += out) { 
     if (-1 == (out = write(fd, buf+count_out, count_in-count_out))) { 
      perror("Problem writing to file"); 
      exit(-1); 
     } 
     } 
    } 
    } 
+0

因此 - 'read()'和'write()'都需要進入while循環。 –

+2

@DigitalTrauma你需要兩個while循環。外層的文件確保你已經讀完了所有的舊文件。內部用於將緩衝區中的所有數據寫入新文件。您需要內部緩衝區,因爲當您提出要求時,write可能不會寫入您要求的所有數據。你可能不得不繼續嘗試,直到全部寫完。 –

+0

是的,這就是對的 –