[C++] 确定两个路径是否参考Windows中的相同文件的最佳方法?


Answers

看到这个问题: 确定是否两个路径引用到C#中的同一文件的最佳方法

问题是关于C#,但答案只是Win32 API调用GetFileInformationByHandle

Question

如何比较2个字符串以确定它们是否在Win32中使用C / C ++引用相同的路径?

虽然这将处理很多情况下,它会错过一些东西:

_tcsicmp(szPath1, szPath2) == 0

例如:

  • 正斜杠/反斜杠

  • 相对/绝对路径。

[编辑]标题更改为匹配现有的C#问题。




一个简单的字符串比较不足以比较相等的路径。 在Windows中,c:\ foo \ bar.txt和c:\ temp \ bar.txt很可能通过文件系统中的符号链接和硬链接指向完全相同的文件。

正确比较路径本质上会迫使你打开这两个文件并比较低级句柄信息。 任何其他方法将有片状结果。

看看这篇关于这个话题的出色的文章。 这个代码是用VB编写的,但是当他调用大部分的方法的时候,这个代码是可以转换到C / C ++的。

http://blogs.msdn.com/vbteam/archive/2008/09/22/to-compare-two-filenames-lucian-wischik.aspx




比较实际的路径字符串将不会产生准确的结果,如果您引用UNC或规范路径(即本地路径以外的任何其他)。

shlwapi.h有一些路径函数 ,可能会用于确定路径是否相同。

它包含了可以在更大范围的函数中使用的像PathIsRoot这样的函数。




你需要做的是获得规范的路径。

对于每个路径,您都要求文件系统转换为规范路径或为您提供唯一标识文件(例如iNode)的标识符。

然后比较规范路径或唯一标识符。

注意:不要试图自己弄清楚文件系统可以用符号链接等方式来处理锥形路径,除非你对文件系统非常熟悉,否则这些链接不易处理。




如果文件存在,你可以打开文件来处理潜在的竞争条件和性能问题,那么应该在任何平台上工作的不完美的解决方案是打开一个文件供自己写,关闭它,然后打开它再次写入打开另一个文件后写入。 由于只能允许写访问是排他性的,如果您能够打开第一个文件而不是第二个文件,那么当您尝试打开这两个文件时,您可能会阻止自己的请求。

(当然,也有可能是系统的其他部分打开了其中一个文件)