有效的方式来遍历包含链接周期的目录树

时间:2014-10-19 13:40:18

标签: algorithm filesystems symlink directory-walk symlink-traversal

是否有更有效的方法来遍历包含链接周期的目录树,而不是跟踪哪些文件已被访问过?

例如,考虑走一个包含这些文件的目录:

symlink "parent" -> ".."
symlink "uh_oh" -> "/"
regular file "reg"
symlink "reg2" -> "reg"

2 个答案:

答案 0 :(得分:0)

根据您的第一个示例,您还应该跟踪访问过哪些目录,但除此之外没有比维护每个文件的访问标记更好的解决方案。

如果有一种可移植的方法来获取已安装文件系统的简短唯一标识符,那么维护标志会更容易。即便如此,您还需要考虑扫描期间发生的mount和umount操作的后果,特别是如果文件系统树包含远程文件系统,这种扫描可能需要很长时间。

理论上,您可以从stafvfs界面获取“文件系统ID”,但实际上并非完全可移植。从Linux发行版引用man statfs

  

没有人知道f_fsid应该包含什么......

     

...一般的想法是f_fsid包含一些随机的东西,使得(f_fsid,ino)对唯一地确定一个文件。某些操作系统使用(变体)设备编号,或设备编号与文件系统类型相结合。有几个操作系统限制只向超级用户发出f_fsid字段(对于非特权用户为零),因为当NFS导出时,该字段用于文件系统的文件句柄,并且将其输出是一个安全问题。

后一个限制 - f_fsid对非特权用户显示为0 - 不违反上面引用的Posix标准,因为该标准包含一个非常通用的disclaimer:“它是未指定statvfs结构的所有成员是否在所有文件系统上都有有意义的值。“

答案 1 :(得分:0)

树行走算法保证您可以访问目录下的每个文件,因此您可以维护搜索列表" root":

,而不是跟踪单个文件。
  • 将初始目录添加到根列表
  • 遍历每个搜索根目录树
  • 对于您找到的每个符号链接,请检查它是否已包含在搜索根目录中。如果不是,请将其添加为新的搜索根。

这样您就可以访问每个文件和目录,永远不会陷入循环,但可能会多次访问文件和目录。只有当您找到现有根的祖先的符号链接时,才会发生这种情况。为避免这样做,您可以在输入之前检查目录是否为搜索根目录。