如何避免遍历无休止的递归目录链接?

时间:2013-11-15 18:09:26

标签: windows recursion filesystems

我有一些使用FindFirstFile()FindNextFile()递归遍历文件系统的功能。这工作正常,但问题是,有时它会遇到某种递归链接。例如,C:\foo\bar链接到C:\foo。这些链接中的大多数是使用重新分析点实现的,因此足以避免遍历到设置了FILE_FLAG_REPARSE_POINT属性的文件夹。但是,在极少数情况下,其中一个链接不会设置该标志,因此代码会陷入无限循环,直到堆栈耗尽。

我的问题是如何检测这些链接以避免无休止地进入它们?

不幸的是,我无法访问重现问题的环境,因此我无法收集更多信息;我必须要做的就是来自Windows错误报告的一些故障转储。我在本地(NTFS)文件系统上看到过这些非重新链接的链接,也可能在远程(SMB)文件系统上看到过这些非重新链接的链接,但我不是百分之百的。

编辑:其中一个转储的详细信息。

在一个案例中,问题文件夹为C:\users\Administrator\AppData\Local\Application Data。这里Application Data部分重复超过700次,并且路径的总长度为12K个字符(24k字节)。由于局部变量,在达到32K限制之前堆栈已经耗尽。这是一台Windows 7计算机,文件系统是NTFS,因此通常Application DataAppData\Local的联结。但是,我的代码没有将此特定文件夹检测为联结。在日志中我可以看到它正在检测其他交叉点,因此这让我相信这是一个环境问题。

1 个答案:

答案 0 :(得分:0)

我想你有办法获得真正的道路?如果是这样,您可以拥有一个访问过的真实路径的结构,以便在递归跟踪目录之前对其进行检查。

最容易实现的是实际路径的哈希表。当需要扩展哈希并且密钥作为路径完整存储时,这会产生巨大的损失。

第二个是基数/特里树来做同样的事情。由于它是树结构,因此前缀节点将共享结构,并且不需要重新进行重组。搜索/插入将是O(n),其中n是路径中的/的数量。

还有更多的选择,但我个人首先要从最简单的实现开始,看看它的表现如何,并且可能使用了大的初始哈希值。