如何在Linux中找到文件系统中的循环?我正在为快速搜索所有文件编制索引(O(1))...我正在使用c编程语言来实现dir.h中的库函数....我可以扫描整个文件系统但它进入一个循环,如果文件系统中有循环(示例循环安装)...如何在文件系统中找到循环..我已经看到当文件系统中有循环时updatedb命令报告...我不明白逻辑......任何人都可以帮忙找到解决方案吗?
答案 0 :(得分:5)
阻止在图中重新扫描节点的一般方法是在传递节点时标记节点,然后忽略标记的节点。如果您不想修改要扫描的图形,这不是非常实用,因此您需要一种在外部标记节点的方法。我能想到在linux下执行此操作的最简单方法是为您访问的每个目录存储device / inode。然后,当您查看目录时,首先检查您是否还没有看到具有相同设备/ inode的任何目录。这不仅可以处理循环,还可以处理彼此合并的树。
要获取设备/ inode编号,请查看stat / fstat函数以及stat结构的st_dev和st_ino成员。
为了存储数据,您可能想要查看hash-table或二叉树。
答案 1 :(得分:2)
顺便说一下。您不需要在文件系统中搜索循环。
您正在索引整个磁盘。所以你不需要遵循符号链接,因为每个文件必须以正常方式访问(没有符号链接)。如果某个磁盘安装了多次,你只需要检查挂载点,只需忽略挂载的其余点即可。
答案 2 :(得分:1)
我在这里找到了关于finding loops in a DAG的有趣评论:
Steinar H. Gunderson写道:
2004年2月26日星期四00:28:32 +0100,Orlondow写道:
...也在Cormen-Leiserson-Rivest,IIC上复制。这是 最简单的 找到。
是的,我实际上有Cormen等人,但它从来没有让我感到震惊 当我想要循环检测时,“强连接组件”。谢谢,我会的 看看它。 : - )
在有向图中查找循环 (你不关心哪个周期) 因为存在一个,你不需要 与SCC一起过火。平原旧的深度 首先搜索DFS(在同一章节中 (CLRS)就足够了。
因此,粗略地说,当您遍历目录树时,创建一个DAG,它表示树的结构,节点处的数据引用文件的inode。然后,您只需检查以确保您不会多次访问节点。
答案 3 :(得分:1)
也许我在这里有点昏暗但不是你创造一个循环的两种方式:
要处理这些问题,您可以在开始编制索引之前获取一个安装列表,并且除了第一个相同的f之外的所有内容都可以获得,并且您可以在索引过程中忽略链接。
答案 4 :(得分:1)
简单的方法。只需对目录树进行深度优先的树遍历,随时随地保留一堆节点。在您访问的每个节点上,如果该节点已经在堆栈中,则您有一个循环。
// here's a stack of nodes
node stack[1000];
walk(node, level){
if (node in stack[0..level-1]) then there is a cycle
else
stack[level] = node
for each subnode x of node
walk(x, level+1)
}
答案 5 :(得分:1)
正如其他人所说,如果你意识到路径是文件名的一部分,除非它是一个循环的符号链接,否则文件系统中没有循环这样的东西。
例如,如果你将一些发行版(比如Debian)引导到循环设备,甚至引导到一个目录,并在Debian机器上执行此操作,那么你现在已经复制了很多东西。
例如,假设你正在运行Debian Lenny,并将它的最小副本引导到/ lenny。
/ lenny / usr / *将与/ usr / *相同。没有“廉价”的方法来避免这种情况。
由于你已经在每个节点上调用了stat()(我假设你正在使用ftw()/ ftw64(),你也可以这样做:
这没有加快扫描速度的危险,但它会大大减少搜索所需的时间。
如果正确使用线程并设置了亲和性,则散列和索引可以在一个核心上发生,而另一个核心是i / o绑定(当多个核心可用时)。
然而,'只是'检查重复的安装是不可能的,另外我确定你的程序会想要返回所有名为'foo'的文件的位置,即使有四个相同的副本要提及
答案 6 :(得分:0)
这通常被称为“循环”。所以你想实现“循环检测”。有很多方法可以做到这一点;我不知道这是否适合家庭工作但是一个简单的,不一定是最优的方法是通过指针追逐。