C# UnauthorizedAccessException无法解决Directory.GetFiles故障
第一次遇到没有访问权限的文件夹时失败 该方法引发UnauthorizedAccessException(可以捕获),但在完成此操作时,该方法已失败/终止 我使用的代码如下所示:C# UnauthorizedAccessException无法解决Directory.GetFiles故障,c#,exception-handling,unauthorized,getfiles,C#,Exception Handling,Unauthorized,Getfiles,第一次遇到没有访问权限的文件夹时失败 该方法引发UnauthorizedAccessException(可以捕获),但在完成此操作时,该方法已失败/终止 我使用的代码如下所示: try { // looks in stated directory and returns the path of all files found getFiles = Directory.GetFiles( @directoryToSearch,
try
{
// looks in stated directory and returns the path of all files found
getFiles = Directory.GetFiles(
@directoryToSearch,
filetype,
SearchOption.AllDirectories);
}
catch (UnauthorizedAccessException)
{
}
据我所知,没有办法事先检查某个文件夹是否定义了访问权限
在我的示例中,我在网络上搜索磁盘,当我遇到根目录访问文件夹时,我的程序失败。为了获得所需级别的控制,您可能应该一次探测一个目录,而不是整个目录树。以下方法使用目录树中找到的所有文件(用户无权访问的文件除外)填充给定的
IList
:
// using System.Linq
private static void AddFiles(string path, IList<string> files)
{
try
{
Directory.GetFiles(path)
.ToList()
.ForEach(s => files.Add(s));
Directory.GetDirectories(path)
.ToList()
.ForEach(s => AddFiles(s, files));
}
catch (UnauthorizedAccessException ex)
{
// ok, so we are not allowed to dig into that directory. Move on.
}
}
//使用System.Linq
私有静态void AddFiles(字符串路径、IList文件)
{
尝试
{
Directory.GetFiles(路径)
托利斯先生()
.ForEach(s=>files.Add);
Directory.GetDirectories(路径)
托利斯先生()
.ForEach(s=>AddFiles(s,files));
}
捕获(未经授权的访问例外)
{
//好的,我们不允许深入那个目录。继续。
}
}
.Net 4的Directory.Enumerate文件确实有效,但您必须注意如何计算可枚举项,以及如何在try-catch块中执行该部分。最大的问题是确保您不会在第一个异常时停止处理(我认为上面的答案有这个问题,如果我错了,请纠正我)
下面的工作原理为您提供了一个可枚举项,这样,如果您要查找第一个匹配项,就不必计算整个文件树,等等
private IEnumerable<String> FindAccessableFiles(string path, string file_pattern, bool recurse)
{
IEnumerable<String> emptyList = new string[0];
if (File.Exists(path))
return new string[] { path };
if (!Directory.Exists(path))
return emptyList;
var top_directory = new DirectoryInfo(path);
// Enumerate the files just in the top directory.
var files = top_directory.EnumerateFiles(file_pattern);
var filesLength = files.Count();
var filesList = Enumerable
.Range(0, filesLength)
.Select(i =>
{
string filename = null;
try
{
var file = files.ElementAt(i);
filename = file.FullName;
}
catch (UnauthorizedAccessException)
{
}
catch (InvalidOperationException)
{
// ran out of entries
}
return filename;
})
.Where(i => null != i);
if (!recurse)
return filesList;
var dirs = top_directory.EnumerateDirectories("*");
var dirsLength = dirs.Count();
var dirsList = Enumerable
.Range(0, dirsLength)
.SelectMany(i =>
{
string dirname = null;
try
{
var dir = dirs.ElementAt(i);
dirname = dir.FullName;
return FindAccessableFiles(dirname, file_pattern, required_extension, recurse);
}
catch (UnauthorizedAccessException)
{
}
catch (InvalidOperationException)
{
// ran out of entries
}
return emptyList;
})
return Enumerable.Concat(filesList, dirsList);
}
private IEnumerable FindAccessableFiles(字符串路径、字符串文件\u模式、布尔递归)
{
IEnumerable emptyList=新字符串[0];
if(File.Exists(path))
返回新字符串[]{path};
如果(!Directory.Exists(path))
返回空列表;
var top_directory=新目录信息(路径);
//枚举顶部目录中的文件。
var files=top\u目录。枚举文件(文件模式);
var filesLength=files.Count();
var filesList=可枚举
.Range(0,文件长度)
.选择(i=>
{
字符串文件名=null;
尝试
{
var file=files.ElementAt(i);
filename=file.FullName;
}
捕获(未经授权的访问例外)
{
}
捕获(无效操作异常)
{
//没有条目了
}
返回文件名;
})
。其中(i=>null!=i);
如果(!递归)
返回文件列表;
var dirs=top_目录。枚举目录(“*”);
var dirsLength=dirs.Count();
var dirsList=可枚举
.范围(0,方向长度)
.SelectMany(i=>
{
字符串dirname=null;
尝试
{
var dir=直接元素(i);
dirname=dir.FullName;
返回FindAccessableFiles(目录名、文件模式、所需扩展名、递归);
}
捕获(未经授权的访问例外)
{
}
捕获(无效操作异常)
{
//没有条目了
}
返回空列表;
})
返回Enumerable.Concat(文件列表,目录列表);
}
欢迎对上述内容进行改进。这是对马尔科姆答案的改进(http://stackoverflow.com/a/9831340/226181). 这将扫描所有逻辑驱动器以查找文件匹配模式,并忽略不可访问的目录
static List<string> SearchFiles(string pattern)
{
var result = new List<string>();
foreach (string drive in Directory.GetLogicalDrives())
{
Console.WriteLine("searching " + drive);
var files = FindAccessableFiles(drive, pattern, true);
Console.WriteLine(files.Count().ToString() + " files found.");
result.AddRange(files);
}
return result;
}
private static IEnumerable<String> FindAccessableFiles(string path, string file_pattern, bool recurse)
{
Console.WriteLine(path);
var list = new List<string>();
var required_extension = "mp4";
if (File.Exists(path))
{
yield return path;
yield break;
}
if (!Directory.Exists(path))
{
yield break;
}
if (null == file_pattern)
file_pattern = "*." + required_extension;
var top_directory = new DirectoryInfo(path);
// Enumerate the files just in the top directory.
IEnumerator<FileInfo> files;
try
{
files = top_directory.EnumerateFiles(file_pattern).GetEnumerator();
}
catch (Exception ex)
{
files = null;
}
while (true)
{
FileInfo file = null;
try
{
if (files != null && files.MoveNext())
file = files.Current;
else
break;
}
catch (UnauthorizedAccessException)
{
continue;
}
catch (PathTooLongException)
{
continue;
}
yield return file.FullName;
}
if (!recurse)
yield break;
IEnumerator<DirectoryInfo> dirs;
try
{
dirs = top_directory.EnumerateDirectories("*").GetEnumerator();
}
catch (Exception ex)
{
dirs = null;
}
while (true)
{
DirectoryInfo dir = null;
try
{
if (dirs != null && dirs.MoveNext())
dir = dirs.Current;
else
break;
}
catch (UnauthorizedAccessException)
{
continue;
}
catch (PathTooLongException)
{
continue;
}
foreach (var subpath in FindAccessableFiles(dir.FullName, file_pattern, recurse))
yield return subpath;
}
}
静态列表搜索文件(字符串模式)
{
var result=新列表();
foreach(目录.GetLogicalDrives()中的字符串驱动器)
{
控制台写入线(“搜索”+驱动器);
var files=FindAccessableFiles(驱动器、模式、true);
Console.WriteLine(files.Count().ToString()+“找到文件”);
result.AddRange(文件);
}
返回结果;
}
私有静态IEnumerable FindAccessableFiles(字符串路径、字符串文件模式、布尔递归)
{
控制台写入线(路径);
var list=新列表();
所需var_extension=“mp4”;
if(File.Exists(path))
{
收益返回路径;
屈服断裂;
}
如果(!Directory.Exists(path))
{
屈服断裂;
}
if(null==文件\u模式)
文件\u pattern=“*”+所需的\u扩展名;
var top_directory=新目录信息(路径);
//枚举顶部目录中的文件。
IEnumerator文件;
尝试
{
files=top_目录。枚举文件(文件模式)。GetEnumerator();
}
捕获(例外情况除外)
{
files=null;
}
while(true)
{
FileInfo file=null;
尝试
{
if(files!=null&&files.MoveNext())
file=files.Current;
其他的
打破
}
捕获(未经授权的访问例外)
{
继续;
}
catch(路径工具异常)
{
继续;
}
产生返回文件.FullName;
}
如果(!递归)
屈服断裂;
IEnumerator-dirs;
尝试
{
dirs=top_目录。枚举目录(“*”).GetEnumerator();
}
捕获(例外情况除外)
{
dirs=null;
}
while(true)
{
DirectoryInfo dir=null;
尝试
{
如果
public static List<string> GetAllAccessibleFiles(string rootPath, List<string> alreadyFound = null)
{
if (alreadyFound == null)
alreadyFound = new List<string>();
DirectoryInfo di = new DirectoryInfo(rootPath);
var dirs = di.EnumerateDirectories();
foreach (DirectoryInfo dir in dirs)
{
if (!((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden))
{
alreadyFound = GetAllAccessibleFiles(dir.FullName, alreadyFound);
}
}
var files = Directory.GetFiles(rootPath);
foreach (string s in files)
{
alreadyFound.Add(s);
}
return alreadyFound;
}
var files = GetAllAccessibleFiles(@"C:\myDirectory");
C:\myDirectory\a\a.txt
C:\myDirectory\a\b.mp3
C:\myDirectory\b\a\a\foo.txt
C:\myDirectory\b\b\b\hello.exe
C:\myDirectory\b\c\bar.jpg
C:\myDirectory\and\so\on.bar
C:\myDirectory\a_file_in_root.bmp
public string[] GetFilesFrom(string dir, string search_pattern, bool recursive)
{
List<string> files = new List<string>();
string[] temp_files = new string[0];
try { temp_files = Directory.GetFiles(dir, search_pattern, SearchOption.TopDirectoryOnly); }
catch { }
files.AddRange(temp_files);
if (recursive)
{
string[] temp_dirs = new string[0];
try { temp_dirs = Directory.GetDirectories(dir, search_pattern, SearchOption.TopDirectoryOnly); }
catch { }
for (int i = 0; i < temp_dirs.Length; i++)
files.AddRange(GetFilesFrom(temp_dirs[i], search_pattern, recursive));
}
return files.ToArray();
}
IEnumerable<String> GetAllFiles(string path, string searchPattern)
{
return System.IO.Directory.EnumerateFiles(path, searchPattern).Union(
System.IO.Directory.EnumerateDirectories(path).SelectMany(d =>
{
try
{
return GetAllFiles(d, searchPattern);
}
catch (UnauthorizedAccessException e)
{
return Enumerable.Empty<String>();
}
}));
}