2011-03-24 73 views
2

我有两个包含文件夹路径的字符串。有没有办法确定他们是否以某种方式指向相同的位置?字符串比较似乎有点不可靠的考虑之类的东西不区分大小写,8.3文件名长度忙玲,SUBST等确定两个目录名是否指向同一目录

为了说明,我怎么能确定这两个指向同一个地方:

String1 = "c:\Program Files\MyFolder\" 
String2 = "C:\PROGRA~1\MYFOLDER" 

回答

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); 
} 
+0

这不仅仅是路径必须是有效的,文件必须存在。虽然很好的答案。 – 2011-03-24 20:20:31

+0

+1。为什么不在这两种情况下(文件和目录)使用'FILE_FLAG_BACKUP_SEMANTICS'? – kobik 2012-03-28 18:58:46

+1

@kobik:我不记得确切地说,它可能不会伤害到在文件上使用它(但它是一个目录需要) – Anders 2012-03-28 22:48:51

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(); 

} 
+0

你怎么知道OP使用.net? – 2011-03-24 10:00:07

+0

好问题。如果不是这两个kernel32.dll函数仍然可以使用。 – Paaland 2011-03-24 10:02:38

2

为了获得最佳性能,您应该路径减少到规范形式。这是8.3(GetShortPathName)和小写。

相关问题