3 回答

TA貢獻1797條經驗 獲得超4個贊
您可以采取兩件事來改進該代碼:
使用
Directory.EnumerateFiles()
和Directory.EnumerateDirectories()
可以避免復制每個目錄中所有文件的名稱。使方法的返回類型
IEnumerable<string>
更容易使用。
我們還需要非常小心由于嘗試訪問受保護的文件和目錄而導致的異常。下面的代碼也很復雜,因為您不允許在塊yield return
內部進行操作try/catch
,因此我們必須稍微重新排列代碼。
(另請注意,我們必須處置從 返回的枚舉器.GetEnumerator()
;通常,當您使用 時,這是自動完成的foreach
,但在這種情況下我們不能 - 因為必須避免yield return
在 a 中執行try/catch
- 所以我們必須使用 useusing
來處置它。)
以下是對原始代碼的修改:
public static IEnumerable<string> GetFiles(string root, string spec)
{
var pending = new Stack<string>(new []{root});
while (pending.Count > 0)
{
var path = pending.Pop();
IEnumerator<string> fileIterator = null;
try
{
fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
}
catch {}
if (fileIterator != null)
{
using (fileIterator)
{
while (true)
{
try
{
if (!fileIterator.MoveNext()) // Throws if file is not accessible.
break;
}
catch { break; }
yield return fileIterator.Current;
}
}
}
IEnumerator<string> dirIterator = null;
try
{
dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
}
catch {}
if (dirIterator != null)
{
using (dirIterator)
{
while (true)
{
try
{
if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
break;
}
catch { break; }
pending.Push(dirIterator.Current);
}
}
}
}
}
例如,以下是如何使用控制臺應用程序列出“C:\”驅動器上所有可訪問的“.txt”文件:
static void Main()
{
foreach (var file in GetFiles("C:\\", "*.txt"))
{
Console.WriteLine(file);
}
}

TA貢獻1785條經驗 獲得超8個贊
更換線路
Console.WriteLine(file); Console.ReadLine();
用一種方法將它們存儲在列表中。
例如
foundFiles.Add(file);
然后,當該方法完成時,您可以從此列表中讀取所有找到的文件路徑。
注意:
這不會產生系統上與過濾器匹配的所有文件。
只有您的應用程序有權訪問其各自目錄的文件才能通過這種方式找到。
例如,Windows目錄和其他用戶的用戶目錄通常受到保護。(假設您在 Windows 上運行)
請記住,某些文件可能會獨立于其目錄而受到保護。
因此,當嘗試讀取它們時,還要考慮讀取可能會失敗的事實。
只需用 try catch 包圍讀取即可。
- 3 回答
- 0 關注
- 209 瀏覽
添加回答
舉報