【问题标题】:Continue Foreach Loop On Error错误时继续 Foreach 循环
【发布时间】:2015-12-28 16:34:47
【问题描述】:

我想在出现错误时继续我的代码,但我不知道如何......

这是我的代码:

foreach(string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories)
{
    Console.WriteLine(path);
}

错误出现在foreach(string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories),我不知道如何继续这个循环

和错误:

未经授权的访问

即使我以管理员身份运行我的代码,也会再次出现此错误

谢谢,

【问题讨论】:

  • 更改您的 c:\ 的访问设置
  • 我也想在其他电脑上工作...
  • 我对你的问题有点困惑。您是否需要权限以便您的代码可以在每个目录上运行,或者您是否希望您的代码跳过它没有权限的目录?
  • 我想跳过那个目录并转到下一个...
  • try-catch 块将允许您的应用在出现错误的情况下继续运行

标签: c# foreach


【解决方案1】:

最好是使用递归搜索而不是使用SearchOption.AllDirectories,而是使用SearchOption.TopDirectoryOnly

如果您使用SearchOption.AllDirectories,即使在处理任何文件/目录之前,一个访问冲突也会破坏您的整个循环。但是如果你使用SearchOption.TopDirectoryOnly,你只会跳过无法访问的内容。

因此,要做到这一点,您可以创建一个接收目录路径作为输入的方法。在该方法中,如果输入目录有子目录(请参阅Directory.GetDirectories(string path) 方法,则在处理目录中的所有文件之前,为每个子目录再次调用该方法(递归调用)。否则,获取文件(见Directory.GetFiles)并立即处理它们。

那么对于上面的方法,一种方法是防止在您无法访问某些文件/目录时代码崩溃是使用try-catch 块来读取每个子目录和文件读取。这样,如果无法访问一个文件/文件夹,您的代码仍将运行,查找处理下一个文件/目录。

或者,您可以使用Directory.GetAccessControl() 每个子目录检查您是否可以事先访问Directory(虽然这个选项相当困难)。

编辑(添加代码):

这样就可以了:

public static List<string> GetAllAccessibleDirectories(string path, string searchPattern) {
    List<string> dirPathList = new List<string>();
    try {
        List<string> childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList(); //use TopDirectoryOnly
        if (childDirPathList == null || childDirPathList.Count <= 0) //this directory has no child
            return null;
        foreach (string childDirPath in childDirPathList) { //foreach child directory, do recursive search
            dirPathList.Add(childDirPath); //add the path
            List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern);
            if (grandChildDirPath != null && grandChildDirPath.Count > 0) //this child directory has children and nothing has gone wrong
                dirPathList.AddRange(grandChildDirPath.ToArray()); //add the grandchildren to the list
        }
        return dirPathList; //return the whole list found at this level
    } catch {
        return null; //something has gone wrong, return null
    }
}

要调用它,你可以这样做

string rootpath = @"C:\DummyRootFolder";
List<string> dirList = GetAllAccessibleDirectories(rootpath, "*.*"); //you get all accessible directories here

dirList中你会得到你搜索的所有目录,如果一路上存在访问冲突,由于try-catch块,它只会影响子目录搜索。

注意rootpath 被排除在方法中。但是如果你也想把它添加到列表中,你可以简单地做

dirList.Insert(0, path); //do this after you get dirList

还有更多complicatedwaysof doing这个使用Directory.GetAccessControlPermissionSet

希望它可以澄清。

【讨论】:

  • 我不明白你的意思...如果可能的话,写代码谢谢
  • 根据您的要求添加的代码,看看它是否阐明了我的意思
  • 很高兴您发现它有帮助! =) 但请注意,此代码很简单但不是最优的。这是因为您只有在尝试阅读它之后才意识到自己违反了某些目录访问控制。这会在一定程度上影响你的表现。因此,以防万一您需要更好的解决方案,您可能需要使用GetAccessControl 方法。
【解决方案2】:

根据文档,出于性能原因,您应该查看 EnumerateDirectories:

https://msdn.microsoft.com/en-us/library/c1sez4sc(v=vs.110).aspx

另外,这个问题似乎之前已经回答过:

Directory.EnumerateFiles => UnauthorizedAccessException

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    这个怎么样:

    foreach (string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories)) {
    
                try { 
                    Console.WriteLine(path);
                } catch (Exception ex) {
                    Console.WriteLine("Unable to access directories in path: " + path);
                }
            }
    

    【讨论】:

    • 您不想捕捉任何类型的异常。您可能希望尽可能明确地捕获异常(在这种情况下)。
    • @Cyber​​neticTwerkGuruOrc 在这种情况下我不同意,因为原始发布者说“我想在出现错误时继续我的代码,但我不知道如何”他没有说他想继续一些错误,但不是其他错误,他说所有错误,这正是我的代码所做的。
    猜你喜欢
    • 1970-01-01
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    相关资源
    最近更新 更多