确定Windows中两个路径引用同一文件的最佳方法是什么?

Ada*_*gen 16 c++ winapi path

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

虽然这会处理很多情况但它会遗漏一些事情:

_tcsicmp(szPath1, szPath2) == 0
Run Code Online (Sandbox Code Playgroud)

例如:

  • 正斜杠/反斜杠

  • 相对/绝对路径.

[编辑]标题已更改为与现有C#问题匹配.

MSN*_*MSN 33

打开与这两个文件CreateFile,叫GetFileInformationByHandle两个,和比较dwVolumeSerialNumber,nFileIndexLow,nFileIndexHigh.如果所有三个都相等,则它们都指向同一个文件:

GetFileInformationByHandle 功能

BY_HANDLE_FILE_INFORMATION 结构体

  • 注意文件应保持打开,否则可能是相同的数字将对应于不同的文件. (4认同)

小智 5

使用来自kernel32.dll的GetFullPathName,这将为您提供文件的绝对路径.然后使用简单的字符串比较将其与您拥有的其他路径进行比较

编辑:代码

TCHAR buffer1[1000];
TCHAR buffer2[1000];
TCHAR buffer3[1000];
TCHAR buffer4[1000];

GetFullPathName(TEXT("C:\\Temp\\..\\autoexec.bat"),1000,buffer1,NULL);
GetFullPathName(TEXT("C:\\autoexec.bat"),1000,buffer2,NULL);
GetFullPathName(TEXT("\\autoexec.bat"),1000,buffer3,NULL);
GetFullPathName(TEXT("C:/autoexec.bat"),1000,buffer4,NULL);
_tprintf(TEXT("Path1: %s\n"), buffer1);
_tprintf(TEXT("Path2: %s\n"), buffer2);
_tprintf(TEXT("Path3: %s\n"), buffer3);
_tprintf(TEXT("Path4: %s\n"), buffer4);
Run Code Online (Sandbox Code Playgroud)

上面的代码将为所有三个路径表示打印相同的路径..之后您可能希望进行不区分大小写的搜索

  • 硬链接允许单个文件具有两个不同的名称.是的,那些只知道对自己和他人有危险的人,Windows确实支持硬链接. (8认同)
  • 这不起作用,因为同一文件可以有多个路径 (2认同)

sth*_*sth 5

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

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


Sty*_*pox 5

文件系统库

从C ++ 17开始,您可以使用标准文件系统库。使用包括它#include <filesystem>。您甚至可以在较旧的C ++版本中访问它,请参见脚注。

您要查找的功能是equivalent在名称空间下std::filesystem

bool std::filesystem::equivalent(const std::filesystem::path& p1, const filesystem::path& p2 );
Run Code Online (Sandbox Code Playgroud)

文档总结:此函数采用两个路径作为参数,如果它们引用相同的文件或目录,则返回true,否则返回false。还有一个noexcept采用第三个参数的重载:std::error_code在其中保存任何可能的错误。

#include <filesystem>
#include <iostream>
//...

int main() {
    std::filesystem::path p1 = ".";
    std::filesystem::path p2 = fs::current_path();
    std::cout << std::filesystem::equivalent(p1, p2));
    //...
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
Run Code Online (Sandbox Code Playgroud)

在C ++ 17之前使用文件系统

要在C ++ 17之前的版本中使用此库,您必须在编译器中启用实验语言功能,并以这种方式包括该库:#include <experimental/filesystem>。然后,您可以在名称空间下使用其功能std::experimental::filesystem。请注意,实验性文件系统库可能与C ++ 17库不同。请参阅此处的文档。
例如:

#include <experimental/filesystem>
//...
std::experimental::filesystem::equivalent(p1, p2);
Run Code Online (Sandbox Code Playgroud)