我有两个包含文件夹路径的字符串。有没有办法确定他们是否以某种方式指向同一位置?考虑到不区分大小写,8.3文件名长度修改,替换等等,字符串比较似乎有点不可靠。
为了说明,我怎样才能确定这两个指向同一个地方:
String1 = "c:\Program Files\MyFolder\"
String2 = "C:\PROGRA~1\MYFOLDER"
答案 0 :(得分:6)
以下代码适用于文件(包括硬链接)和目录(包括联结),但两条路径都必须有效!
#include <windows.h>
#include <stdio.h>
BOOL ArePathsEqual(LPCTSTR path1,LPCTSTR path2)
{
BY_HANDLE_FILE_INFORMATION bhfi1,bhfi2;
HANDLE h1, h2 = NULL;
DWORD access = 0;
DWORD share = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
h1 = CreateFile(path1,access,share,NULL,OPEN_EXISTING,(GetFileAttributes(path1)&FILE_ATTRIBUTE_DIRECTORY)?FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
if (INVALID_HANDLE_VALUE != h1)
{
if (!GetFileInformationByHandle(h1,&bhfi1)) bhfi1.dwVolumeSerialNumber = 0;
h2 = CreateFile(path2,access,share,NULL,OPEN_EXISTING,(GetFileAttributes(path2)&FILE_ATTRIBUTE_DIRECTORY)?FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
if (!GetFileInformationByHandle(h2,&bhfi2)) bhfi2.dwVolumeSerialNumber = bhfi1.dwVolumeSerialNumber + 1;
}
CloseHandle(h1);
CloseHandle(h2);
return INVALID_HANDLE_VALUE != h1 && INVALID_HANDLE_VALUE != h2
&& bhfi1.dwVolumeSerialNumber==bhfi2.dwVolumeSerialNumber
&& bhfi1.nFileIndexHigh==bhfi2.nFileIndexHigh
&& bhfi1.nFileIndexLow==bhfi2.nFileIndexLow ;
}
void main()
{
BOOL bRet = ArePathsEqual("c:\\program files","c:\\progra~1");
printf("ArePathsEqual: %d\n",bRet);
}
答案 1 :(得分:2)
为了获得最佳性能,您应该减少规范形式的路径。这是8.3(GetShortPathName)和小写。
答案 2 :(得分:1)
这是一个C#样本。如果你使用其他语言,那么这个想法是一样的。使用来自kernel32.dll的GetLongPathName和/或GetShortPathName并进行比较:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetLongPathName(
[MarshalAs(UnmanagedType.LPTStr)]
string path,
[MarshalAs(UnmanagedType.LPTStr)]
StringBuilder longPath,
int longPathLength
);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)]
string path,
[MarshalAs(UnmanagedType.LPTStr)]
StringBuilder shortPath,
int shortPathLength
);
function bool PathsAreEqual(string path1, string path2)
{
StringBuilder shortPath1 = new StringBuilder(255);
StringBuilder shortPath2 = new StringBuilder(255);
GetShortPathName(path1, shortPath1, shortPath1.Capacity);
GetShortPathName(path2, shortPath2, shortPath2.Capacity);
return shortPath1.ToString().ToLower() == shortPath2.ToString().ToLower();
}