使用Directory.GetFiles(…)时拒绝访问该路径

我正在运行下面的代码并在下面获得例外。 我是否被迫将此函数放入try catch中,还是以其他方式递归获取所有目录? 我可以编写自己的递归函数来获取文件和目录。 但我想知道是否有更好的方法。

// get all files in folder and sub-folders var d = Directory.GetFiles(@"C:\", "*", SearchOption.AllDirectories); // get all sub-directories var dirs = Directory.GetDirectories(@"C:\", "*", SearchOption.AllDirectories); 

“拒绝访问路径’C:\ Documents and Settings \’。”

如果你想在失败后继续下一个文件夹,那么是的; 你必须自己做。 我建议使用Stack (深度优先)或Queue (bredth优先)而不是递归,以及迭代器块( yield return ); 那么你可以避免堆栈溢出和内存使用问题。

例:

  public static IEnumerable GetFiles(string root, string searchPattern) { Stack pending = new Stack(); pending.Push(root); while (pending.Count != 0) { var path = pending.Pop(); string[] next = null; try { next = Directory.GetFiles(path, searchPattern); } catch { } if(next != null && next.Length != 0) foreach (var file in next) yield return file; try { next = Directory.GetDirectories(path); foreach (var subdir in next) pending.Push(subdir); } catch { } } } 

您可以设置程序,以便只能以管理员身份运行。

Visual Studio中

 Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings 

单击它后,将创建一个名为app.manifest的项目属性文件夹下的文件,您可以取消选中Enable ClickOnce Security Settings选项

打开该文件并更改此行:

  

至:

   

这将使程序需要管理员权限,并且它将保证您有权访问该文件夹。

好吧,你要么避开你没有权限的目录,要么你没有,但是当访问被拒绝时你会优雅地回复。

如果选择第一个选项,则需要确保知道它们是哪个目录,并且还要确保线程标识的权限不会更改。 这很棘手,容易出错; 我不推荐它用于生产质量的系统。

第二种选择看起来更合适。 使用try / catch块并跳过任何“禁止”目录。

我知道这个问题有些陈旧,但今天我遇到了同样的问题,我发现下面的文章详细解释了’文件夹递归’解决方案。

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

不幸的是,这[ 使用GetDirectories()方法 ]存在问题。 其中的关键是可以配置您尝试读取的某些文件夹,以便当前用户可以不访问它们。 该方法抛出UnauthorizedAccessException,而不是忽略您具有受限访问权限的文件夹。 但是,我们可以通过创建自己的递归文件夹搜索代码来规避这个问题。

……然后详细介绍解决方案:

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

已经指出你需要自己做,所以我想我会分享我的解决方案,避免收集。 应该注意的是,这将忽略所有错误,而不仅仅是AccessDenied。 要更改它,您可以使catch块更具体。

  IEnumerable GetFiles(string folder, string filter, bool recursive) { string [] found = null; try { found = Directory.GetFiles(folder, filter); } catch { } if (found!=null) foreach (var x in found) yield return x; if (recursive) { found = null; try { found = Directory.GetDirectories(folder); } catch { } if (found != null) foreach (var x in found) foreach (var y in GetFiles(x, filter, recursive)) yield return y; } }