列出系统驱动器以外的驱动器中的所有文件会抛出UnauthorizedAccessException
。
我该如何解决这个问题?
是否可以向我的应用程序授予所需的访问权限?
Directory.GetFiles("S:\\", ...)
这是一个可以上课的课程:
public static class FileDirectorySearcher
{
public static IEnumerable<string> Search(string searchPath, string searchPattern)
{
IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern);
foreach (string file in files)
{
yield return file;
}
IEnumerable<string> directories = GetDirectories(searchPath);
foreach (string directory in directories)
{
files = Search(directory, searchPattern);
foreach (string file in files)
{
yield return file;
}
}
}
private static IEnumerable<string> GetDirectories(string directory)
{
IEnumerable<string> subDirectories = null;
try
{
subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (subDirectories != null)
{
foreach (string subDirectory in subDirectories)
{
yield return subDirectory;
}
}
}
private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern)
{
IEnumerable<string> files = null;
try
{
files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (files != null)
{
foreach (string file in files)
{
yield return file;
}
}
}
}
您可以像这样使用它:
IEnumerable<string> filesOrDirectories = FileDirectorySearcher.Search(@"C:\", "*.txt");
foreach (string fileOrDirectory in filesOrDirectories)
{
// Do something here.
}
这是递归的,但是使用yield可以减少内存占用(在我的测试中为10KB以下)。如果只需要匹配模式的文件而不是目录,只需将EnumerateFileSystemEntries
替换为EnumerateFiles
。
是否允许[[您访问驱动器?如果未从Visual Studio运行该程序,则可以访问该驱动器吗?是否在项目的“安全性”页面(“ Security Page, Project Designer”)中定义了限制性权限?
是导致异常的SearchOption.AllDirectories选项。
但是当我仅使用Directories.GetFiles列出直接文件时,它就可以使用。
这对我来说足够好。
解决递归列表问题的任何方法吗?
public static IEnumerable<string> ListFiles(string baseDir)
{
EnumerationOptions opt = new EnumerationOptions();
opt.RecurseSubdirectories = true;
opt.ReturnSpecialDirectories = false;
//opt.AttributesToSkip = FileAttributes.Hidden | FileAttributes.System;
opt.AttributesToSkip = 0;
opt.IgnoreInaccessible = true;
var tmp = Directory.EnumerateFileSystemEntries(baseDir, "*", opt);
return tmp;
}