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 关注
- 167 浏览
添加回答
举报