尝试从没有权限的位置添加文件时如何处理UnauthorizedAccessException

我试图以这种方式从文件夹中获取所有文件:

try { string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories); } catch (UnauthorizedAccessException) { throw; } 

如果我的根文件夹包含用户UnauthorizedAccessException访问的文件夹,则会捕获UnauthorizedAccessException并且我的数组为空并且所有递归都失败。

我如何处理这种情况并确保我的代码在没有权限的情况下忽略位置但是从具有权限的位置添加文件?

请参阅另一篇文章中的SafeFileEnumerator 。 我过去使用过SafeFileEnumerator代码并取得了成功。 当您只是无法访问单个文件时,它可以防止丢失整个枚举,因此您仍然可以遍历可以访问的文件。

编辑:我的版本与我链接的版本略有不同,所以让我分享我的版本。

 public static class SafeFileEnumerator { public static IEnumerable EnumerateDirectories(string parentDirectory, string searchPattern, SearchOption searchOpt) { try { var directories = Enumerable.Empty(); if (searchOpt == SearchOption.AllDirectories) { directories = Directory.EnumerateDirectories(parentDirectory) .SelectMany(x => EnumerateDirectories(x, searchPattern, searchOpt)); } return directories.Concat(Directory.EnumerateDirectories(parentDirectory, searchPattern)); } catch (UnauthorizedAccessException ex) { return Enumerable.Empty(); } } public static IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOpt) { try { var dirFiles = Enumerable.Empty(); if (searchOpt == SearchOption.AllDirectories) { dirFiles = Directory.EnumerateDirectories(path) .SelectMany(x => EnumerateFiles(x, searchPattern, searchOpt)); } return dirFiles.Concat(Directory.EnumerateFiles(path, searchPattern)); } catch (UnauthorizedAccessException ex) { return Enumerable.Empty(); } } } 

用法示例:

 foreach(string fileName in SafeFileEnumerator.EnumerateFiles(folderPath, "*" + extension, SearchOption.AllDirectories)) { //Do something with filename, store into an array or whatever you want to do. } 

您可以使用FileSystemInfo对象和递归来完成此任务:

 static List files = new List(); static void MyMethod() { DirectoryInfo dir = new DirectoryInfo(folderBrowserDialog1.SelectedPath); ProcessFolder(dir.GetFileSystemInfos()); } static void ProcessFolder(IEnumerable fsi) { foreach (FileSystemInfo info in fsi) { // We skip reparse points if ((info.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) { Debug.WriteLine("Skipping reparse point '{0}'", info.FullName); return; } if ((info.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { // If our FileSystemInfo object is a directory, we call this method again on the // new directory. try { DirectoryInfo dirInfo = (DirectoryInfo)info; ProcessFolder(dirInfo.GetFileSystemInfos()); } catch (Exception ex) { // Skipping any errors // Really, we should catch each type of Exception - // this will catch -any- exception that occurs, // which may not be the behavior we want. Debug.WriteLine("{0}", ex.Message); break; } } else { // If our FileSystemInfo object isn't a directory, we cast it as a FileInfo object, // make sure it's not null, and add it to the list. var file = info as FileInfo; if (file != null) { files.Add(file.FullName); } } } } 

MyMethod获取您选择的路径并使用它创建DirectoryInfo对象,然后调用GetFileSystemInfos()方法并将其传递给ProcessFolder方法。

ProcessFolder方法查看每个FileSystemInfo对象,跳过重新分析点 ,如果FileSystemInfo对象是目录,则再次调用ProcessFolder方法 – 否则,它将FileSystemInfo对象强制转换为FileInfo对象,确保它不为null,然后添加列表的文件名。

更多阅读:

  • FileSystemInfo类
  • DirectoryInfo类
  • FileInfo类