Как обрабатывать UnauthorizedAccessException при попытке добавить файлы из местоположения без разрешения
Я пытаюсь получить все файлы из папки таким образом:
try
{
string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories);
}
catch (UnauthorizedAccessException)
{
throw;
}
Если моя корневая папка содержит папку, для которой у пользователя нет доступа к доступу, UnauthorizedAccessException
пойман и мой массив пуст, и вся рекурсия не удалась.
Как я могу обработать этот случай и убедиться, что мой код игнорирует местоположения без разрешения, но добавляет файлы из местоположения с разрешениями?
Ответы
Ответ 1
см. SafeFileEnumerator в этом другом сообщении. Я использовал код SafeFileEnumerator в прошлом с успехом. Это предотвращает потерю всего перечисления, когда у вас просто нет доступа к одному файлу, чтобы вы все еще могли перебирать файлы, к которым вы можете получить доступ.
EDIT: версия, которую я имею, немного отличается от той, с которой я связан, поэтому позвольте мне поделиться с вами версией.
public static class SafeFileEnumerator
{
public static IEnumerable<string> EnumerateDirectories(string parentDirectory, string searchPattern, SearchOption searchOpt)
{
try
{
var directories = Enumerable.Empty<string>();
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<string>();
}
}
public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOpt)
{
try
{
var dirFiles = Enumerable.Empty<string>();
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<string>();
}
}
}
Пример использования:
foreach(string fileName in SafeFileEnumerator.EnumerateFiles(folderPath, "*" + extension, SearchOption.AllDirectories))
{
//Do something with filename, store into an array or whatever you want to do.
}
Ответ 2
Вы можете использовать объекты и рекурсию FileSystemInfo для выполнения этого:
static List<string> files = new List<string>();
static void MyMethod() {
DirectoryInfo dir = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
ProcessFolder(dir.GetFileSystemInfos());
}
static void ProcessFolder(IEnumerable<FileSystemInfo> 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 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, а затем добавляет имя файла в список.
Дополнительная информация: