最好是使用递归搜索而不是使用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.GetAccessControl和PermissionSet
希望它可以澄清。