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

2024-03-17

我的代码是这样的:

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 文件吗?


引用自POSIX 读目录 https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html:

如果文件被删除或添加到 最近的目录之后 调用 opendir() 或 rewinddir(), 是否随后调用 readdir() 返回该文件的条目是 未指定。

所以,我的猜测是……这要看情况。

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

而且,作为进一步的一点,在这段时间之间readdir()函数返回并且你尝试unlink()该文件,其他一些进程可能已删除该文件和您的unlink() fails.


Edit

我用这个程序测试过:

#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;
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 readdir() 读取目录时删除文件 的相关文章

  • VSTS 构建失败/发布无法在 bin 文件夹中找到 roslyn\csc.exe

    我们有一个网站项目 安装了以下 nuget 软件包 Microsoft CodeDom Providers DotNetCompilerPlatform 1 0 8 Microsoft Net Compilers 2 4 0 The web
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • 隐式方法组转换陷阱

    我想知道为什么给定代码的输出 在 LinqPad 中执行 void Main Compare1 Action Main Dump Compare2 Main Dump bool Compare1 Delegate x return x Ac
  • C++ 非类型参数包扩展

    我正在编写由单一类型参数化的模板函数 并且具有可变数量的相同类型 而不是不同类型 的参数 它应该检查第一个值是否在其余值中 我想这样写 include
  • 如何从 List 中的字符串中删除数字/数字?

    我有一个字符串列表 List
  • 使用 Selenium for C# 登录 Facebook

    我一直在使用 Selenium C 框架并尝试进行 facebook 登录 但没有任何运气 这是我到目前为止得到的 基于这篇文章 使用 Selenium 测试 Facebook Connect 应用程序 https stackoverflo
  • 'goto *foo' 其中 foo 不是指针。这是什么?

    我正在玩标签作为值 https gcc gnu org onlinedocs gcc Labels as Values html并最终得到这段代码 int foo 0 goto foo 我的 C C 经验告诉我 foo means dere
  • 正则表达式删除某些字符周围不需要的空格

    我正在尝试从 JavaScript 文件中删除一些不需要的空格 并在将文件发送到客户端之前使用 C 和 Regex 组合文件 我有一个JavascriptHandler处理 js 文件 效果很好 这是我用来 打包 JavaScript 的函
  • Azure 2012 年 10 月 SDK 损坏 UseDevelopmentStorage=true

    有人尝试过使用 usedevelopmentstorage true 连接字符串的 2012 年 10 月 Azure sdk 吗 CloudStorageAccount Parse UseDevelopmentStorage true 抛
  • 控制器中的异常处理 (ASP.NET MVC)

    当您自己的代码抛出异常并从控制器中的操作调用时 应该如何处理 我看到很多最佳实践的例子 其中根本没有 try catch 语句 例如 从存储库访问数据 public ViewResult Index IList
  • 从窗口内容截取屏幕截图(无边框)

    我正在寻找有关如何使用 C 将表单内容保存在位图中的解决方案 我已经尝试过使用 DrawToBitmap 但它捕获了所有带边框的窗口 这就是这段代码的结果 public static Bitmap TakeDialogScreenshot
  • Create CFrameWnd 给出了第一次机会异常——为什么?

    我正在尝试使用基于 CFrameWnd 的代码编写一个简单的 MFC 应用程序 该应用程序在可滚动窗口中绘制 下面的代码改编自 Prosise Programming Windows with MFC 第 2 版 第 89ff 页 当我在调
  • 在 ncurses 中使用退格键

    我设置了一个简单的 ncurses 程序 它使用 getch 一次读取一个字符并将它们复制到缓冲区中 我遇到的问题是检测到按下退格键 这是相关代码 while buffer i c getch EOF i if c n break else
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • C 中的 N 依赖注入 - 比链接器定义的数组更好的方法?

    Given a 库模块 在下文中称为Runner 它作为可重复使用的组件 无需重新编译 即静态链接库 中应用程序分区架构的 而不是主分区 请注意 它仅包含main 出于演示目的 Given a set 顺序无关 调用的其他模块 对象Call
  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • 编译器可以报告未知属性的错误吗?即使有范围?

    在N3291 7 6 1 3 5 属性语法和语义 decl attr grammar 关于如何属性是用我读过的源代码写的 使用一个属性范围令牌是有条件支持的 实现定义的行为 and For an 属性标记本国际标准中未指定 该行为是实现定义
  • 具有多种类型的 C# 泛型类型推断

    我有以下通用方法 用于将一种类型的输入对象序列化为超类型 如下所示 public string SerialiseAs
  • 什么时候使用静态库需要头文件?

    如果我在 Linux 中用 C 创建一个静态库并生成 a 文件 我 或其他人 如何使用该库 例如 我的库定义了一个类 我认为仅仅提供 a 文件是不够的 还需要提供头文件 我如何知道 a 文件必须提供哪些头文件 例如 我是否需要提供我的库代码

随机推荐