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()的操作异步添加到目录中。”但也许最好避免这样!?