需要恢复在Catch块之后尝试

从VB6时代开始,当我通过系统上的目录递归时,我能够以相对适当的方式使用“on next error next”。 如果我的“foreach”循环遇到Permission Denied或Access Denied错误,我所要做的就是调用“resume next”语句。

然而,在C#中,这不存在,我理解为什么。 但是,我很难想象如何在C#中实现这一点。

我试图通过我的硬盘上的目录进行递归并填充TreeView控件。

private void PopulateTree(string dir, TreeNode node) { try { // get the information of the directory DirectoryInfo directory = new DirectoryInfo(dir); // loop through each subdirectory foreach (DirectoryInfo d in directory.GetDirectories("*", SearchOption.AllDirectories)) { // create a new node TreeNode t = new TreeNode(d.Name); // populate the new node recursively PopulateTree(d.FullName, t); node.Nodes.Add(t); // add the node to the "master" node } // lastly, loop through each file in the directory, and add these as nodes foreach (FileInfo f in directory.GetFiles()) { // create a new node TreeNode t = new TreeNode(f.Name); // add it to the "master" node.Nodes.Add(t); } } catch (System.Exception e) { MessageBox.Show(e.Message, "Error Loading Directories", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } 

代码预计会有效。 但是,当它到达Windows 7计算机上的"C:\\Documents and Settings"文件夹时,catch块会捕获“拒绝访问”错误(我期望)。 我想要做的是继续使用系列中的下一个文件夹。

所以问题是,我怎样才能在C#中实现这一目标?

我的研究显示了使用TRY … CATCH块的共同意见,但它并没有告诉我如何做一些如上所述我想做的事情。

注意:我也尝试修改代码以检查属性如下,但它也失败了。

 private void PopulateTree(string dir, TreeNode node) { try { // get the information of the directory DirectoryInfo directory = new DirectoryInfo(dir); if (directory.Attributes == FileAttributes.ReparsePoint || directory.Attributes == FileAttributes.System) { Console.Write("Access denied to folder."); } else { // loop through each subdirectory foreach (DirectoryInfo d in directory.GetDirectories("*", SearchOption.AllDirectories)) { // create a new node TreeNode t = new TreeNode(d.Name); // populate the new node recursively PopulateTree(d.FullName, t); node.Nodes.Add(t); // add the node to the "master" node } // lastly, loop through each file in the directory, and add these as nodes foreach (FileInfo f in directory.GetFiles()) { // create a new node TreeNode t = new TreeNode(f.Name); // add it to the "master" node.Nodes.Add(t); } } } catch (System.Exception e) { MessageBox.Show(e.Message, "Error Loading Directories", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } 

将try / catch块移动到foreach循环中,因此您可以在try块中使用填充代码。 这样,遇到exception时就不会退出循环。

 foreach(var item in col) { try { //do stuff with item } catch { //yes, this is empty, but in this case it is okay as there is no other way } } 

我认为你选择子目录的方法是有缺陷的,这就是为什么你得到访问exception – 你必须排除系统目录,所以像这样的东西应该工作:

 var subDirectories = directory.GetDirectories() .Where(d => (d.Attributes & FileAttributes.ReparsePoint) ==0 && (d.Attributes & FileAttributes.System) == 0); foreach (DirectoryInfo d in subDirectories) { //... } 

在使用directory.GetDirectories("*", SearchOption.AllDirectories)的版本中directory.GetDirectories("*", SearchOption.AllDirectories)特别要求包含系统目录 – SearchOption.AllDirectories将包括系统目录和重新分析点。 来自MSDN :

此方法的缺点是,如果指定根目录下的任何一个子目录导致DirectoryNotFoundException或UnauthorizedAccessException,则整个方法将失败并且不返回任何目录。 使用GetFiles方法时也是如此。 如果必须在特定子文件夹上处理这些exception,则必须手动遍历目录树,如以下示例所示。

而不是尝试捕捉整个事物,为什么不在你需要的地方做它。

  private void PopulateTree(string dir,TreeNode node)
     {
         //获取目录的信息
         DirectoryInfo目录= new DirectoryInfo(dir); 

// loop through each subdirectory foreach (DirectoryInfo d in directory.GetDirectories("*", SearchOption.AllDirectories)) { try { // create a new node TreeNode t = new TreeNode(d.Name); // populate the new node recursively PopulateTree(d.FullName, t); node.Nodes.Add(t); // add the node to the "master" node } catch (System.Exception e) { MessageBox.Show(e.Message, "Error Loading Directories", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } // lastly, loop through each file in the directory, and add these as nodes foreach (FileInfo f in directory.GetFiles()) { // create a new node TreeNode t = new TreeNode(f.Name); // add it to the "master" node.Nodes.Add(t); } }

对于这个特定的实例(查找文件的情况),我有一个解决方法,避免exception问题后的恢复(见下文)。

问题是GetFiles()/ GetDirectories()或EnumerateFiles()。GetEnumerator()强制评估Enumerable,从而导致exception被抛出。

有关代码示例,请参阅https://stackoverflow.com/a/9831340/89584 。