2015-05-04 69 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

相关问题