需要恢复在Catch块之后尝试

时间:2011-03-13 15:35:50

标签: c#

来自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);
        }

    }

4 个答案:

答案 0 :(得分:7)

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

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
  }
}

答案 1 :(得分:4)

我认为你选择子目录的方法是有缺陷的,这就是你获得访问异常的原因 - 你必须排除系统目录,所以这样的东西应该有效:

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)的版本中,具体要求包含系统目录 - SearchOption.AllDirectories将包含系统目录和重新分析点。来自MSDN

  

这种方法的弱点在于   如果任何一个子目录下   指定的根导致a   DirectoryNotFoundException或   UnauthorizedAccessException,整个   方法失败并返回否   目录。当你这样做时也是如此   使用GetFiles方法。如果你有   处理特定的这些例外   子文件夹,你必须手动走   目录树,如图所示   以下示例。

答案 2 :(得分:0)

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

private void PopulateTree(string dir, TreeNode node)
    {
        // get the information of the directory
        DirectoryInfo directory = 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); } }

答案 3 :(得分:0)

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

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

请参阅https://stackoverflow.com/a/9831340/89584以获取代码示例。