2011-03-24 78 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)和小寫。

相關問題