搜索指定名称文件遇System.UnauthorizedAccessException问题求助
嘿,我明白你遇到的困扰了——用Directory.GetFiles递归搜索整个驱动器时,动不动就触发权限异常,还直接中断了搜索,太闹心了对吧?
原代码的问题所在
你原来的代码用SearchOption.AllDirectories会一次性尝试遍历所有子目录,只要有一个目录没有访问权限,整个搜索就会抛出异常;而且你的catch块直接吞掉了所有异常,导致整个驱动器的搜索直接终止,很多正常目录都没机会遍历到。另外还有个小细节:catch(exception ex)里的exception应该大写成Exception哦。
靠谱的解决方案:手动递归遍历,跳过无权目录
正确的做法是逐个目录遍历,遇到无权访问的目录就跳过,而不是中断整个搜索流程。我们可以写一个递归方法,用延迟加载(yield return)来高效处理文件搜索:
public static IEnumerable<string> SearchFiles(string rootPath, string searchPattern) { // 先获取当前目录下的目标文件 try { // 过滤系统文件的话,在这里加判断 foreach (var filePath in Directory.GetFiles(rootPath, searchPattern)) { var fileInfo = new FileInfo(filePath); // 跳过带系统标记的文件 if ((fileInfo.Attributes & FileAttributes.System) != FileAttributes.System) { yield return filePath; } } // 递归遍历所有子目录 foreach (var subDir in Directory.GetDirectories(rootPath)) { foreach (var filePath in SearchFiles(subDir, searchPattern)) { yield return filePath; } } } catch (UnauthorizedAccessException) { // 遇到无权访问的目录,直接跳过 yield break; } catch (DirectoryNotFoundException) { // 目录在遍历过程中被删除/不存在了,同样跳过 yield break; } }
调用这个方法的主代码
把原来的循环改成调用上面的方法就行:
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady)) { foreach (var file in SearchFiles(d.RootDirectory.FullName, fileName)) { Console.WriteLine(file); } }
为什么这个方法更好?
- 不会中断整个搜索:遇到无权目录只会跳过当前目录,其他有权限的目录依然会被正常遍历
- 内存更高效:用
yield return延迟返回结果,不会一次性把所有文件路径加载到内存里 - 精准处理异常:只捕获我们预期的权限异常和目录不存在异常,其他未知异常会正常抛出,方便调试
- 可灵活过滤:如果要筛选系统文件/隐藏文件,直接在遍历文件的时候加属性判断就行
内容的提问来源于stack exchange,提问作者sublimeaces
相关产品推荐
相关产品推荐

