如何判断文件夹是否为递归文件夹复制的子文件夹?

5
我正在尝试实现一个文件夹复制方法,该方法在循环中调用FindFirstFileFindNextFile,并可能在任何子文件夹上递归地调用自身。
为了防止明显的无限循环,我需要确保目标文件夹不是源文件夹的子文件夹。问题是如何做到这一点?我的想法是将DOS路径转换为特定设备路径(需要找出如何),但似乎还有更多内容。
因此,我正在针对以下情况进行测试:
我设置了My Documents文件夹以将其重定向到网络共享的\\Server\Home\UserA\Documents,而且该文件夹还映射到客户端机器上的驱动器R:。所以这意味着所有以下文件夹:
"R:\Documents\Subfolder1"
"\\Server\Home\UserA\Documents\Subfolder1"
"C:\Users\UserA\Documents\Subfolder1"

技术上讲,它们指向同一个物理位置,即位于“我的文档”子文件夹中。

问题是如何可靠地知道这一点?


如果您正在遍历文件夹层次结构,那么您期望遇到映射到同一文件夹的多个文件夹吗?除非您使用符号链接或联接(可以在迭代期间检测到)。 - Remy Lebeau
哦,这可以很容易地完成而不需要符号链接。比如,如果我将c:\Folder1指定为源文件夹,c:\Folder1\Folder2指定为目标文件夹。 - c00000fd
1个回答

2
使用 GetFileInformationByHandle 函数来检索目标目录及每个可能的匹配项的卷序列号和文件索引。如果序列号和文件索引都相同,则它们是同一目录。
请注意,您需要在 CreateFile 中使用FILE_FLAG_BACKUP_SEMANTICS 标志才能打开对目录的句柄。(您不需要备份特权来这样做。)
克隆卷可能具有相同的卷序列号(我不确定 Windows 是否强制更改序列号),因此向用户提供禁用此检查的选项可能是明智的。

谢谢,这是一个很好的解决方案。不过我该给最终用户什么选项呢?“ [x] 挂断应用程序并在我的磁盘上创建一个巨大的文件夹 ” :) - c00000fd
1
"[x]闭嘴,我知道我在做什么" :-) 但说真的,我的命令行应用程序有一个/nofileids选项。另一方面,只有我使用它,所以我不需要担心它会被误解...你可以将其隐藏在注册表设置中或其他地方。或者,如果您想明确支持此场景而无需用户干预,则可以在检测到可能的递归时创建一个具有唯一名称的临时文件,并查看它是否出现在“其他卷”上。 - Harry Johnston
哈哈,好笑。我应该加一个像那样的“彩蛋”。但是,说真的,我怎么检测无限递归?你知道,无限循环类型。 - c00000fd
在最一般的情况下,我想你可能需要跟踪每个目录的卷序列号和文件索引(源和目标都是如此),这样您就可以知道是否已经看到一个。但是,根据您处理联接点和符号链接的方式,只需要将顶级目标文件夹与每个源文件夹进行比较即可。 - Harry Johnston
符号链接是具有FILE_ATTRIBUTE_REPARSE_POINT属性的链接,对吧。但是“联接点”是什么? - c00000fd
符号链接和联接点都是使用重解析点实现的。 FILE_ATTRIBUTE_REPARSE_POINT 应该可以检测到两者。 - Harry Johnston

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接