c# – DirectoryInfo.EnumerateFiles(…)导致UnauthorizedAccessException(和其他异常)

前端之家收集整理的这篇文章主要介绍了c# – DirectoryInfo.EnumerateFiles(…)导致UnauthorizedAccessException(和其他异常)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近需要枚举一个整个文件系统,寻找特定类型的文件进行审计.由于对要扫描的文件系统的权限有限,这导致我遇到了几个例外.其中最流行的是 UnauthorizedAccessException,对我的懊恼,PathTooLongException.

这些通常不会是一个问题,除了它们使IEnumerable无效,阻止我无法完成扫描.

解决方法

为了解决这个问题,我创建了一个替换文件系统枚举器.虽然它可能不完美,但它执行得相当快,并且陷入了我遇到的两个例外.它会找到与传递给它的搜索模式匹配的任何目录或文件.
  1. // This code is public domain
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using log4net;
  8.  
  9. public class FileSystemEnumerable : IEnumerable<FileSystemInfo>
  10. {
  11. private ILog _logger = LogManager.GetLogger(typeof(FileSystemEnumerable));
  12.  
  13. private readonly DirectoryInfo _root;
  14. private readonly IList<string> _patterns;
  15. private readonly SearchOption _option;
  16.  
  17. public FileSystemEnumerable(DirectoryInfo root,string pattern,SearchOption option)
  18. {
  19. _root = root;
  20. _patterns = new List<string> { pattern };
  21. _option = option;
  22. }
  23.  
  24. public FileSystemEnumerable(DirectoryInfo root,IList<string> patterns,SearchOption option)
  25. {
  26. _root = root;
  27. _patterns = patterns;
  28. _option = option;
  29. }
  30.  
  31. public IEnumerator<FileSystemInfo> GetEnumerator()
  32. {
  33. if (_root == null || !_root.Exists) yield break;
  34.  
  35. IEnumerable<FileSystemInfo> matches = new List<FileSystemInfo>();
  36. try
  37. {
  38. _logger.DebugFormat("Attempting to enumerate '{0}'",_root.FullName);
  39. foreach (var pattern in _patterns)
  40. {
  41. _logger.DebugFormat("Using pattern '{0}'",pattern);
  42. matches = matches.Concat(_root.EnumerateDirectories(pattern,SearchOption.TopDirectoryOnly))
  43. .Concat(_root.EnumerateFiles(pattern,SearchOption.TopDirectoryOnly));
  44. }
  45. }
  46. catch (UnauthorizedAccessException)
  47. {
  48. _logger.WarnFormat("Unable to access '{0}'. Skipping...",_root.FullName);
  49. yield break;
  50. }
  51. catch (PathTooLongException ptle)
  52. {
  53. _logger.Warn(string.Format(@"Could not process path '{0}\{1}'.",_root.Parent.FullName,_root.Name),ptle);
  54. yield break;
  55. } catch (System.IO.IOException e)
  56. {
  57. // "The symbolic link cannot be followed because its type is disabled."
  58. // "The specified network name is no longer available."
  59. _logger.Warn(string.Format(@"Could not process path (check SymlinkEvaluation rules)'{0}\{1}'.",e);
  60. yield break;
  61. }
  62.  
  63.  
  64. _logger.DebugFormat("Returning all objects that match the pattern(s) '{0}'",string.Join(",",_patterns));
  65. foreach (var file in matches)
  66. {
  67. yield return file;
  68. }
  69.  
  70. if (_option == SearchOption.AllDirectories)
  71. {
  72. _logger.DebugFormat("Enumerating all child directories.");
  73. foreach (var dir in _root.EnumerateDirectories("*",SearchOption.TopDirectoryOnly))
  74. {
  75. _logger.DebugFormat("Enumerating '{0}'",dir.FullName);
  76. var fileSystemInfos = new FileSystemEnumerable(dir,_patterns,_option);
  77. foreach (var match in fileSystemInfos)
  78. {
  79. yield return match;
  80. }
  81. }
  82. }
  83. }
  84.  
  85. IEnumerator IEnumerable.GetEnumerator()
  86. {
  87. return GetEnumerator();
  88. }
  89. }

用法相当简单.

  1. //This code is public domain
  2. var root = new DirectoryInfo(@"c:\wherever");
  3. var searchPattern = @"*.txt";
  4. var searchOption = SearchOption.AllDirectories;
  5. var enumerable = new FileSystemEnumerable(root,searchPattern,searchOption);

人们可以自由使用它,如果他们觉得有用.

猜你在找的C#相关文章