Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用readdir()读取目录时删除文件_C - Fatal编程技术网

C 使用readdir()读取目录时删除文件

C 使用readdir()读取目录时删除文件,c,C,我的代码是这样的: DIR* pDir = opendir("/path/to/my/dir"); struct dirent pFile = NULL; while ((pFile = readdir())) { // Check if it is a .zip file if (subrstr(pFile->d_name,".zip") { // It is a .zip file, delete it, and the matching log file

我的代码是这样的:

DIR* pDir = opendir("/path/to/my/dir");
struct dirent pFile = NULL;
while ((pFile = readdir())) {
   // Check if it is a .zip file
   if (subrstr(pFile->d_name,".zip") {
      // It is a .zip file, delete it, and the matching log file
      char zipname[200];
      snprintf(zipname, sizeof(zipname), "/path/to/my/dir/%s", pFile->d_name);
      unlink(zipname);
      char* logname = subsstr(zipname, 0, strlen(pFile->d_name)-4); // Strip of .zip
      logname = appendstring(&logname, ".log"); // Append .log
      unlink(logname);
}
closedir(pDir);
(此代码未经测试,仅作为示例)

问题是:当使用readdir()在目录中循环时,是否允许删除目录中的文件? 或者readdir()还会找到已删除的.log文件吗?

引用自:

如果文件从中删除或添加到 在最近的 调用opendir()或rewinddir(), 是否继续调用readdir() 返回该文件的条目 未指明

所以,我猜。。。视情况而定

它取决于操作系统、一天中的时间、添加/删除文件的相对顺序

另外,在
readdir()
函数返回和您尝试
unlink()
文件之间,其他进程可能已经删除了该文件,您的
unlink()
失败


编辑

我用这个程序进行了测试:

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
  struct dirent *de;
  DIR *dd;

  /* create files `one.zip` and `one.log` before entering the readdir() loop */
  printf("creating `one.log` and `one.zip`\n");
  system("touch one.log"); /* assume it worked */
  system("touch one.zip"); /* assume it worked */

  dd = opendir("."); /* assume it worked */
  while ((de = readdir(dd)) != NULL) {
    printf("found %s\n", de->d_name);
    if (strstr(de->d_name, ".zip")) {
      char logname[1200];
      size_t i;
      if (*de->d_name == 'o') {
        /* create `two.zip` and `two.log` when the program finds `one.zip` */
        printf("creating `two.zip` and `two.log`\n");
        system("touch two.zip"); /* assume it worked */
        system("touch two.log"); /* assume it worked */
      }
      printf("unlinking %s\n", de->d_name);
      if (unlink(de->d_name)) perror("unlink");
      strcpy(logname, de->d_name);
      i = strlen(logname);
      logname[i-3] = 'l';
      logname[i-2] = 'o';
      logname[i-1] = 'g';
      printf("unlinking %s\n", logname);
      if (unlink(logname)) perror("unlink");
    }
  }
  closedir(dd); /* assume it worked */
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空){
结构方向*de;
DIR*dd;
/*在进入readdir()循环之前,创建文件'one.zip'和'one.log'*/
printf(“创建`one.log`和`one.zip`\n”);
系统(“touch one.log”);/*假设它工作正常*/
系统(“touch one.zip”);/*假设它工作正常*/
dd=opendir(“.”;/*假设它工作*/
而((de=readdir(dd))!=NULL){
printf(“找到%s\n”,de->d\u名称);
if(strstr(de->d_name,.zip”)){
char logname[1200];
尺寸i;
如果(*de->d_name=='o'){
/*当程序找到'one.zip'时,创建'two.zip'和'two.log'*/
printf(“创建'two.zip'和'two.log`\n”);
系统(“touch two.zip”);/*假设它工作正常*/
系统(“touch two.log”);/*假设它工作正常*/
}
printf(“取消链接%s\n”,de->d\u名称);
如果(取消链接(de->d_name))或(“取消链接”);
strcpy(logname,de->d_name);
i=strlen(logname);
日志名[i-3]=“l”;
logname[i-2]=“o”;
logname[i-1]=“g”;
printf(“取消链接%s\n”,日志名);
如果(取消链接(logname))或(“取消链接”);
}
}
closedir(dd);/*假设它有效*/
返回0;
}

在我的计算机上,
readdir()
查找已删除的文件,但找不到在
opendir()
readdir()之间创建的文件。但在另一台计算机上可能会有所不同;如果我用不同的选项编译,在我的计算机上可能会有所不同;如果我升级内核,可能会有所不同

我发现下一页描述了这个问题的解决方案


我正在测试我的新Linux参考书。Linux编程接口由Michael Kerrisk编写,上面说:

int max_open = sysconf(_SC_OPEN_MAX);
for (int i = 0; i < max_open; ++i)
    close(i);
SUSv3明确指出,未指定readdir()是否返回自上次调用opendir()或rewinddir()以来添加或删除的文件名。自上次此类调用以来未添加或删除的所有文件名都保证返回

我认为还未确定的是尚未扫描的元素会发生什么。返回条目后,无论是否取消当前目录的链接,都将100%保证不再返回该条目

还要注意第二句提供的担保。由于您将不处理其他文件,只取消与zip文件当前条目的链接,因此SUSv3保证将返回所有其他文件。日志文件发生的情况未定义。readdir()可能返回它,也可能不返回,但在您的情况下,它不应该有害

我之所以探究这个问题,是为了找到一种在exec()之前关闭子进程中的文件描述符的有效方法

Stevens在APUE中建议的方法是执行以下操作:

int max_open = sysconf(_SC_OPEN_MAX);
for (int i = 0; i < max_open; ++i)
    close(i);
int max\u open=sysconf(\u SC\u open\u max);
对于(int i=0;i

但是我正在考虑使用类似于OP中的代码来扫描/dev/fd/目录,以准确地知道需要关闭哪些fd。(我要特别注意的是,跳过DIR句柄中包含的dirfd。)

LOL@
man 2 readdir
:“这不是您感兴趣的函数。”同一手册页上说:“目录项表示文件;文件可以从目录中删除,也可以与readdir()的操作异步添加到目录中。”但也许最好避免这样!?