如何使用 'Directory.getFiles' 获取磁盘上具有特定扩展名的所有文件并将它们保存在列表中
How can i get all files on disk with a specific extension using 'Directory.getFiles' and save them in a list
我正在做一个控制台项目,其目标是在整个磁盘中搜索扩展名为“.config”的所有文件
我试过类似的方法:
foreach (string file in Directory.GetFiles("C:\", "*.config", SearchOption.AllDirectories))
{
Console.WriteLine(file);
Console.ReadLine();
}
但给了我一个错误 "denied access to path (...)"。
在互联网上我找到了这段代码:
Stack<string> pending = new Stack<string>();
pending.Push("C:\");
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, "*.config");
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next)
{
Console.WriteLine(file);
Console.ReadLine();
}
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
但它只显示总是在 'enter' 中单击的路径,我想将这些 files/path 保存在列表中。
有人可以帮忙吗?
替换行
Console.WriteLine(file);
Console.ReadLine();
使用将它们存储在列表中的方法。
例如
foundFiles.Add(file);
然后当该方法完成时,您可以从此列表中读取所有找到的文件路径。
备注:
这不会在系统上产生 all 个与过滤器匹配的文件。
通过这种方式只能找到您的应用程序可以访问其各自目录的文件。
例如 Windows 目录和其他用户的用户目录通常是受保护的。 (假设您在 Windows 上 运行)
请记住,某些文件可能会独立于其目录受到保护。
因此,在尝试读取它们时,还要考虑读取可能会失败的事实。
只需用 try catch 包含读取内容。
关于错误 "denied access to path (...)",有时您必须 运行 Visual Studio 作为管理员才能访问 C:\ 驱动器中的某些文件夹。
您可以做两件事来改进该代码:
- 使用
Directory.EnumerateFiles()
和 Directory.EnumerateDirectories()
避免复制每个目录中所有文件的名称。
- 将方法设为 return 类型
IEnumerable<string>
以使其更易于使用。
我们还需要非常小心因试图访问受保护的文件和目录而导致的异常。下面的代码也很复杂,因为您不允许从 try/catch
块中 yield return
,因此我们必须稍微重新安排代码。
(另请注意,我们必须处理 .GetEnumerator()
中的枚举数 return;通常这会在您使用 foreach
时自动完成,但在这种情况下我们不能- 因为必须避免在 try/catch
中执行 yield return
- 所以我们必须使用 using
来处理它。)
这是对您的原始代码的修改:
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);
}
}
我正在做一个控制台项目,其目标是在整个磁盘中搜索扩展名为“.config”的所有文件
我试过类似的方法:
foreach (string file in Directory.GetFiles("C:\", "*.config", SearchOption.AllDirectories))
{
Console.WriteLine(file);
Console.ReadLine();
}
但给了我一个错误 "denied access to path (...)"。
在互联网上我找到了这段代码:
Stack<string> pending = new Stack<string>();
pending.Push("C:\");
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, "*.config");
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next)
{
Console.WriteLine(file);
Console.ReadLine();
}
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
但它只显示总是在 'enter' 中单击的路径,我想将这些 files/path 保存在列表中。
有人可以帮忙吗?
替换行
Console.WriteLine(file);
Console.ReadLine();
使用将它们存储在列表中的方法。
例如
foundFiles.Add(file);
然后当该方法完成时,您可以从此列表中读取所有找到的文件路径。
备注:
这不会在系统上产生 all 个与过滤器匹配的文件。
通过这种方式只能找到您的应用程序可以访问其各自目录的文件。
例如 Windows 目录和其他用户的用户目录通常是受保护的。 (假设您在 Windows 上 运行)
请记住,某些文件可能会独立于其目录受到保护。
因此,在尝试读取它们时,还要考虑读取可能会失败的事实。
只需用 try catch 包含读取内容。
关于错误 "denied access to path (...)",有时您必须 运行 Visual Studio 作为管理员才能访问 C:\ 驱动器中的某些文件夹。
您可以做两件事来改进该代码:
- 使用
Directory.EnumerateFiles()
和Directory.EnumerateDirectories()
避免复制每个目录中所有文件的名称。 - 将方法设为 return 类型
IEnumerable<string>
以使其更易于使用。
我们还需要非常小心因试图访问受保护的文件和目录而导致的异常。下面的代码也很复杂,因为您不允许从 try/catch
块中 yield return
,因此我们必须稍微重新安排代码。
(另请注意,我们必须处理 .GetEnumerator()
中的枚举数 return;通常这会在您使用 foreach
时自动完成,但在这种情况下我们不能- 因为必须避免在 try/catch
中执行 yield return
- 所以我们必须使用 using
来处理它。)
这是对您的原始代码的修改:
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);
}
}