当Directory.GetFiles()被拒绝访问时忽略文件夹/文件

我试图显示在选定的目录(和任选的子目录)中find的所有文件的列表。 我遇到的问题是,当GetFiles()方法遇到无法访问的文件夹时,它会引发exception,并停止进程。

我如何忽略这个exception(并忽略受保护的文件夹/文件)并继续添加可访问的文件到列表中?

try { if (cbSubFolders.Checked == false) { string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath); foreach (string fileName in files) ProcessFile(fileName); } else { string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories); foreach (string fileName in files) ProcessFile(fileName); } lblNumberOfFilesDisplay.Enabled = true; } catch (UnauthorizedAccessException) { } finally {} 

您将不得不手动执行recursion; 不要使用AllDirectories – 一次查看一个文件夹,然后尝试从子目录中获取文件。 未经testing,但下面的东西(注意使用委托,而不是build立一个数组):

 using System; using System.IO; static class Program { static void Main() { string path = ""; // TODO ApplyAllFiles(path, ProcessFile); } static void ProcessFile(string path) {/* ... */} static void ApplyAllFiles(string folder, Action<string> fileAction) { foreach (string file in Directory.GetFiles(folder)) { fileAction(file); } foreach (string subDir in Directory.GetDirectories(folder)) { try { ApplyAllFiles(subDir, fileAction); } catch { // swallow, log, whatever } } } } 

这个简单的function运作良好,并符合问题的要求。

 private List<string> GetFiles(string path, string pattern) { var files = new List<string>(); try { files.AddRange(Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly)); foreach (var directory in Directory.GetDirectories(path)) files.AddRange(GetFiles(directory, pattern)); } catch (UnauthorizedAccessException) { } return files; } 

另请检查如何:通过目录树迭代 。

一个简单的方法是使用文件列表和目录的队列。 它保存了记忆。 如果使用recursion程序来执行相同的任务,则可能会导致OutOfMemoryexception。 输出:List中添加的文件按照从上到下(宽度优先)的目录树进行组织。

 public static List<string> GetAllFilesFromFolder(string root, bool searchSubfolders) { Queue<string> folders = new Queue<string>(); List<string> files = new List<string>(); folders.Enqueue(root); while (folders.Count != 0) { string currentFolder = folders.Dequeue(); try { string[] filesInCurrent = System.IO.Directory.GetFiles(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly); files.AddRange(filesInCurrent); } catch { // Do Nothing } try { if (searchSubfolders) { string[] foldersInCurrent = System.IO.Directory.GetDirectories(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly); foreach (string _current in foldersInCurrent) { folders.Enqueue(_current); } } } catch { // Do Nothing } } return files; } 

脚步:

  1. 排队队列中的根
  2. 在一个循环中,使其出列,将该目录中的文件添加到列表中,然后将子文件夹添加到队列中。
  3. 重复直到队列为空。

这应该回答这个问题。 我忽略了通过子目录的问题,我假设你已经明白了。

当然,你不需要为此提供一个独立的方法,但是你可能会发现它也是validationpath有效的有用的地方,并处理调用GetFiles()时可能遇到的其他exception。

希望这可以帮助。

 private string[] GetFiles(string path) { string[] files = null; try { files = Directory.GetFiles(path); } catch (UnauthorizedAccessException) { // might be nice to log this, or something ... } return files; } private void Processor(string path, bool recursive) { // leaving the recursive directory navigation out. string[] files = this.GetFiles(path); if (null != files) { foreach (string file in files) { this.Process(file); } } else { // again, might want to do something when you can't access the path? } } 

有关处理UnauthorisedAccessException问题的解决scheme,请参阅https://stackoverflow.com/a/10728792/89584

如果任何对GetFiles()或GetDirectories()的调用位于具有权限混合的文件夹上,则上述所有解决scheme都将会丢失文件和/或目录。

我知道这个问题有点老,但我今天也有这个问题,我发现下面的文章,详细解释了“文件夹recursion”的解决scheme。

文章承认GetDirectories()方法的缺陷…:

不幸的是,这[ 使用GetDirectories()方法 ]有问题。 其中的关键是,您尝试读取的某些文件夹可能被configuration,以便当前用户可能无法访问它们。 该方法不会忽略限制访问的文件夹,而是抛出UnauthorizedAccessException。 但是,我们可以通过创build我们自己的recursion文件夹search代码来绕过这个问题。

…然后详细介绍解决scheme:

http://www.blackwasp.co.uk/FolderRecursion.aspx