我有一個要求,我想Environment.SpecialFolder從檔案路徑中獲取值。
例如 -
string filePath = @"C:\Program Files (x86)\text.txt"
//SpecialFolder sf = GetSpecialFolderAssociatedWithPath(filePath); // sf will be ProgramFilesX86
//Need something similar
我想進一步使用sf來生成另一個路徑,所以如果我們得到與那個特定的路徑對應的路徑SpecialFolder,那也可以。
uj5u.com熱心網友回復:
您可以這樣做(假設您想獲取特殊檔案夾的實際列舉值):
public static Environment.SpecialFolder? FindSpecialFolder(string filePath)
{
filePath = Path.GetFullPath(filePath);
foreach (var folder in Enum.GetValues<Environment.SpecialFolder>())
{
string directory = Environment.GetFolderPath(folder);
if (directory.Length > 0 && filePath.StartsWith(directory, StringComparison.OrdinalIgnoreCase))
return folder;
}
return null;
}
請注意,我必須回傳一個可為空的值,因為 Microsoft 沒有遵循他們自己的指導方針,并且沒有在Environment.SpecialFolder列舉中包含一個特殊的“無”零值,我可以回傳以指示“未找到”。
用法將是這樣的:
string filePath = @"C:\Program Files (x86)\text.txt";
var folder = FindSpecialFolder(filePath);
if (folder == null)
Console.WriteLine("No folder found");
else
Console.WriteLine(folder.Value);
如果你想要路徑和列舉值,你可以在一個元組中回傳它們:
public static (Environment.SpecialFolder? specialFolder, string? directory) FindSpecialFolder(string filePath)
{
filePath = Path.GetFullPath(filePath);
foreach (var folder in Enum.GetValues<Environment.SpecialFolder>())
{
string directory = Environment.GetFolderPath(folder);
if (directory.Length > 0 && filePath.StartsWith(directory, StringComparison.OrdinalIgnoreCase))
return (folder, directory);
}
return default;
}
你可以像這樣使用:
var folder = FindSpecialFolder(filePath);
if (folder.specialFolder == null)
Console.WriteLine("No folder found");
else
Console.WriteLine($"{folder.specialFolder.Value}: {folder.directory}");
實際上,一些特殊檔案夾可能嵌套在其他特殊檔案夾下,例如您可能有:
C:\Path1\Path2
C:\Path1\Path2\Path3
在這種情況下,上面的代碼將回傳它匹配的第一個路徑,而不是最長的;即尋找"C:\Path1\Path2\Path3\SomeFile.txt"可能會回傳特殊檔案夾"C:\Path1\Path2"而不是"C:\Path1\Path2\Path3".
如果要處理這種可能性,則必須找到最長的匹配路徑,例如:
public static (Environment.SpecialFolder? specialFolder, string? directory) FindSpecialFolder(string filePath)
{
filePath = Path.GetFullPath(filePath);
int longest = 0;
Environment.SpecialFolder? longestFolder = null;
string? longestDir = null;
foreach (var folder in Enum.GetValues<Environment.SpecialFolder>())
{
string directory = Environment.GetFolderPath(folder);
if (directory.Length > longest && filePath.StartsWith(directory, StringComparison.OrdinalIgnoreCase))
{
longestDir = directory;
longestFolder = folder;
longest = directory.Length;
}
}
return (longestFolder, longestDir);
}
并像這樣使用它:
var folder = FindSpecialFolder(filePath);
if (folder.specialFolder == null)
Console.WriteLine("No folder found");
else
Console.WriteLine($"{folder.specialFolder.Value}: {folder.directory}");
要注意的另一件事是多個特殊檔案夾可能具有相同的路徑。在這種情況下,無法區分它們,因此代碼只會回傳它找到的第一個匹配項。
還要注意使用filePath = Path.GetFullPath(filePath);來確保將相對路徑轉換為絕對路徑,否則匹配可能不起作用。
uj5u.com熱心網友回復:
我不知道有任何現有的功能可以做到這一點,但滾動你自己的功能并不太難。例如:
private static bool TryGetSpecialFolderAssociatedWithPath(string filePath, out Environment.SpecialFolder sf)
{
foreach (Environment.SpecialFolder value in Enum.GetValues(typeof(Environment.SpecialFolder)))
{
string path = Environment.GetFolderPath(value);
if (!string.IsNullOrEmpty(path) && filePath.StartsWith(path "\\"))
{
sf = value;
return true;
}
}
sf = default; // Actually the same as Desktop
return false;
}
用法:
string filePath = @"C:\Program Files (x86)\text.txt";
if (TryGetSpecialFolderAssociatedWithPath(filePath, out Environment.SpecialFolder sf))
{
Console.WriteLine("Special folder is " sf);
}
這會產生以下輸出:
Special folder is ProgramFilesX86
需要注意的一點是,我在回傳的路徑上附加了一個反斜杠。如果我不這樣做,那么代碼片段會ProgramFiles在ProgramFilesX86.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/466473.html
上一篇:如何在linq和C#中使用條件或
下一篇:無法從Api反序列化json
