How do I resolve a canonical filename in Windows?

此生再无相见时 提交于 2019-11-29 03:04:49

问题


If I have a string that resolves to a file path in Windows, is there an accepted way to get a canonical form of the file name?

For example, I'd like to know whether

C:\stuff\things\etc\misc\whatever.txt

and

C:\stuff\things\etc\misc\other\..\whatever.txt

actually point to the same file or not, and store the canonical form of the path in my application.

Note that simple string comparisons won't work, nor will any RegEx magic. Remember that we have things like NTFS reparse points to deal with since Windows 2000 and the new Libraries structure in Windows 7.


回答1:


Short answer: not really.

There is no simple way to get the canonical name of a file on Windows. Local files can be available via reparse points, via SUBST. Do you want to deal with NTFS junctions? Windows shortcuts? What about \\?\-escaped filenames

Remote files can be available via mapped drive letter or via UNC. Is that the UNC to the origin server? Are you using DFS? Is the server using reparse points, etc.? Is the server available by more than one name? What about the IP address? Does it have more than one IP address?

So, if you're looking for something like the inode number on Windows, it ain't there. See, for example, this page.




回答2:


Roger is correct, there is no simple way. If the volume supports file a unique file index, you can open the file and call GetFileInformationByHandle, but this will not work on all volumes.

The Windows API call GetFullPathName may be the best simple approach.




回答3:


Using FileInfo (example in C#):

FileInfo info1 = new FileInfo(@"C:\stuff\things\etc\misc\whatever.txt");
FileInfo info2 = new FileInfo(@"C:\stuff\things\etc\misc\other\..\whatever.txt");
if (info1.FullName.Equals(info2.FullName)) {
    Console.WriteLine("yep, they're equal");
}
Console.WriteLine(info1.FullName);
Console.WriteLine(info2.FullName);

Output is:

yep, they're equal
C:\stuff\things\etc\misc\whatever.txt
C:\stuff\things\etc\misc\whatever.txt




回答4:


GetFinalPathNameByHandle appears to do what your asking for, which is available starting with Windows Vista.




回答5:


jheddings has a nice answer, but since you didn't indicate which language you are using, I thought I'd give a Python way to do it that also works from the command line, using os.path.abspath:

> python -c "import os.path; print os.path.abspath('C:\stuff\things\etc\misc\other\..\whatever.txt')"
C:\stuff\things\etc\misc\whatever.txt



回答6:


I would use System.IO.Path.GetFullPath. It takes a string as an input (C:\stuff\things\etc\misc\other..\whatever.txt in your case) and will output a string (C:\stuff\things\etc\misc\whatever.txt).




回答7:


I guess I'm a little late, but you can use System.IO.Path.GetFullPath("C:\stuff\things\etc\misc\other..\whatever.txt") and it will return "C:\stuff\things\etc\misc\whatever.txt"




回答8:


To get canonical path you should use PathCanonicalize function.



来源:https://stackoverflow.com/questions/1816691/how-do-i-resolve-a-canonical-filename-in-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!