tôi thích Yona's answer, nhưng tôi muốn nó đến: đường dẫn
- Hỗ trợ UNC
- Nói cho tôi biết nếu đường dẫn không tồn tại
- Sử dụng lặp lại thay vì đệ quy (vì nó chỉ sử dụng đệ quy đuôi)
- Giảm thiểu số lượng cuộc gọi đến Path.Combine (để giảm thiểu chuỗi nối).
/// <summary>
/// Gets the exact case used on the file system for an existing file or directory.
/// </summary>
/// <param name="path">A relative or absolute path.</param>
/// <param name="exactPath">The full path using the correct case if the path exists. Otherwise, null.</param>
/// <returns>True if the exact path was found. False otherwise.</returns>
/// <remarks>
/// This supports drive-lettered paths and UNC paths, but a UNC root
/// will be returned in title case (e.g., \\Server\Share).
/// </remarks>
public static bool TryGetExactPath(string path, out string exactPath)
{
bool result = false;
exactPath = null;
// DirectoryInfo accepts either a file path or a directory path, and most of its properties work for either.
// However, its Exists property only works for a directory path.
DirectoryInfo directory = new DirectoryInfo(path);
if (File.Exists(path) || directory.Exists)
{
List<string> parts = new List<string>();
DirectoryInfo parentDirectory = directory.Parent;
while (parentDirectory != null)
{
FileSystemInfo entry = parentDirectory.EnumerateFileSystemInfos(directory.Name).First();
parts.Add(entry.Name);
directory = parentDirectory;
parentDirectory = directory.Parent;
}
// Handle the root part (i.e., drive letter or UNC \\server\share).
string root = directory.FullName;
if (root.Contains(':'))
{
root = root.ToUpper();
}
else
{
string[] rootParts = root.Split('\\');
root = string.Join("\\", rootParts.Select(part => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(part)));
}
parts.Add(root);
parts.Reverse();
exactPath = Path.Combine(parts.ToArray());
result = true;
}
return result;
}
Đối với UNC đường dẫn, các trường hợp này vào thư mục gốc (\\ Server \ Share) trong trường hợp tiêu đề chứ không phải là trường hợp chính xác vì nó sẽ là rất nhiều làm việc nhiều hơn để cố gắng xác định máy chủ từ xa chính xác tên trường hợp và tên trường hợp chính xác của cổ phiếu. Nếu bạn muốn thêm hỗ trợ đó, bạn sẽ phải sử dụng các phương thức P/Invoke như NetServerEnum và NetShareEnum. Nhưng những thứ đó có thể chậm và chúng không hỗ trợ tính năng lọc phía trước chỉ với máy chủ và chia sẻ các tên mà bạn quan tâm.
Dưới đây là một phương pháp đơn vị thử nghiệm cho TryGetExactPath (sử dụng Visual Studio Testing Extensions):
[TestMethod]
public void TryGetExactPathNameTest()
{
string machineName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Environment.MachineName.ToLower());
string[] testPaths = new[]
{
@"C:\Users\Public\desktop.ini",
@"C:\pagefile.sys",
@"C:\Windows\System32\cmd.exe",
@"C:\Users\Default\NTUSER.DAT",
@"C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies",
@"C:\Program Files (x86)",
@"Does not exist",
@"\\Nas\Main\Setups",
@"\\Nas\Main\Setups\Microsoft\Visual Studio\VS 2015\vssdk_full.exe",
@"\\" + machineName + @"\C$\Windows\System32\ActionCenter.dll",
@"..",
};
Dictionary<string, string> expectedExactPaths = new Dictionary<string, string>()
{
{ @"..", Path.GetDirectoryName(Environment.CurrentDirectory) },
};
foreach (string testPath in testPaths)
{
string lowercasePath = testPath.ToLower();
bool expected = File.Exists(lowercasePath) || Directory.Exists(lowercasePath);
string exactPath;
bool actual = FileUtility.TryGetExactPath(lowercasePath, out exactPath);
actual.ShouldEqual(expected);
if (actual)
{
string expectedExactPath;
if (expectedExactPaths.TryGetValue(testPath, out expectedExactPath))
{
exactPath.ShouldEqual(expectedExactPath);
}
else
{
exactPath.ShouldEqual(testPath);
}
}
else
{
exactPath.ShouldBeNull();
}
}
}
Nguồn
2015-04-11 13:16:09
NTFS chắc chắn là trường hợp * nhạy cảm *. Đó là API Windows không nhất quán về nó. –
Nếu bạn thay thế 'return di.Name.ToUpper();' bằng 'return di.FullName.ToUpper();' (FullName), nó sẽ làm việc với các đường dẫn UNC. :-) – ygoe
Tôi thích câu trả lời này, nhưng tôi đã thích nghi nó trong câu trả lời của mình với phương thức TryGetExactPath hỗ trợ đường dẫn UNC, cho tôi biết đường dẫn không tồn tại hay không và sử dụng phép lặp thay vì đệ quy để giảm thiểu các cuộc gọi đến Path.Combine. –