2015-05-04 72 views
1

我已經寫了一個函數來重命名目錄中的文件,以便它們以數字順序命名。不幸的是,這個函數似乎丟掉了一些文件並重新命名了一些文件。可能,我不明白readdir()和rename()後面的邏輯。任何人都可以幫忙,這裏是我的代碼的摘錄;readdir()如何與rename()一起使用?

while(((entry->readdir(dirp))!=NULL) 
{ 
    strcpy(t1_string,entry->d_name); 
    exception1=strcmp(entry->d_name,"."); 
    exception2=strcmp(entry->d_name,".."); 
    exception3=strcmp(entry->d_name,".svn"); 
    if((exception1!=0)&&(exception2!=0)&&(exception3!=0)) 
    { 
    token2=strchr(t1_string,'.'); //extension part 
    num_files++; 
    if(num_files%4==1) 
     utt++; 
    sprintf(utt_n,"%d",utt); 
    strcpy(newfilename, utt_s); //utt_s is a constant string 
    strcat(newfilename,utt_n); 
    strcat(newfilename,token2); 
    rename(entry->d_name,newfilename); 
    } 
} //End of the while loop 
+0

用'printf(「mv -i%s%s \ n」,entry-> d_name,newfilename)替換'rename(entry-> d_name,newfilename);''end看看它試圖做什麼。然後:運行創建的腳本。 – joop

+0

所需的新名稱是所需的順序,但舊名稱以紊亂的方式出現,沒有觀察到順序。讓我尋找另一種方式來做到這一點。 – user4898148

+0

用單個snprintf()替換一堆strcat(),並確保newfilename足夠大。 – joop

回答

2

這很可能是由於競爭條件造成的;你基本上在修改數據結構的同時迭代它。當然,數據結構是文件系統關於目錄中文件名稱的想法。

正如在評論中指出,甚至還有在Open Group的規格頁面這個確切的情況下爲readdir()警告:

如果一個文件被去除或最近一次調用之後添加到目錄到opendir()rewinddir(),後續調用readdir()是否返回該文件的條目是未指定的。

一個更好的辦法是做在兩個階段:

  1. 收集所有的名字。
  2. 做所需的重命名。

當然,您必須爲重命名失敗做好準備,因爲其他進程可以與您並行地重命名或刪除文件。

+0

'scandir'(POSIX.1-2008的一部分)對階段1很有幫助。 –

+1

事實上,我的系統中readdir的手冊頁直接調用了這個風險:如果文件從目錄中刪除或添加到目錄在最近一次調用opendir()或rewinddir()之後,未指定對readdir()的後續調用是否返回該文件的條目。 –

+0

@JohnHascall好的,謝謝。 – unwind

相關問題