【问题标题】:Level 2 I/O in Linux using readdir() possible?Linux 中使用 readdir() 的级别 2 I/O 可能吗?
【发布时间】:2014-07-04 13:23:34
【问题描述】:

我正在尝试遍历目录结构并打开该结构中的每个文件。为了遍历,我使用了 opendir() 和 readdir()。由于我已经拥有该实体,因此构建路径并打开文件似乎很愚蠢——这可能会迫使 Linux 找到我刚刚遍历的目录和文件。

2 级 I/O(打开、创建、读取、写入)需要路径。是否有任何调用来打开目录中的文件名,或者打开给定 inode 的文件?

【问题讨论】:

  • “这大概会迫使 Linux 找到我刚刚遍历的目录和文件。” - 我会做一些挖掘/测量,看看这是否值得尝试优化。您在这里的假设可能不正确。
  • 如果没有别的,它会迫使我在我不想的时候建立路径!
  • 有(相当新的)openat() 系统调用。然而,你从 opendir()/readdir() 中得到的并没有太多可以传递给 openat() 调用。

标签: linux readdir


【解决方案1】:

您可能应该使用nftw(3) 递归遍历文件树。

否则,以可移植的方式,使用例如构造您的目录 + 文件名路径。

snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dirname, filename);

(或者也许使用asprintf(3),但不要忘记稍后free 结果)

要回答有关在目录中打开文件的问题,您可以使用 Linux 或 POSIX2008 特定 openat(2)。但我相信你真的应该使用nftw 或者像上面建议的那样构建你的路径。另请阅读open(2) 中的O_PATHO_TMPFILE

顺便说一句,内核必须多次访问该目录(实际上,元数据由文件系统内核代码缓存),因为另一个进程可能在您遍历它时写入其中。

甚至不要考虑通过它的 inode 号打开文件:这将违反几个文件系统抽象! (但可能很难通过疯狂和恶心的技巧,例如debugfs - 这可能会严重损害您的文件系统!!)。

请记住,文件通常是inodes,并且可以有零个(一个进程在保持打开的文件描述符的同时做了open 然后unlink(2) 一个文件)、一个(这是通常的情况)或多个(例如/foo/bar1/gee/bar2 可以使用 link(2) ....) 文件名进行硬链接。

某些文件系统(例如 FAT ...)没有真正的 inode。在这种情况下,内核会伪造一些东西。

【讨论】:

  • openat 正是我想要的,但为什么不断地重建字符串路径更好?
  • 因为openat 可能无法在每个内核或文件系统上工作或可用。构造字符串比调用文件系统系统调用(至少进入文件系统缓存,甚至可能进入磁盘)要快得多 - 所以可以忽略不计。
猜你喜欢
  • 2012-08-06
  • 2012-03-08
  • 2018-12-18
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
相关资源
最近更新 更多