Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22

Чем заменить Directory.GetFiles?

10.08.2018, 15:01. Показов 4423. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ни когда раньше не задумывался над этим, а тут пришлось по системным каталогам собирать информацию и я с удивлением обнаружил неприятные свойства функции Directory.GetFiles. Хотя это и не является секретом, но в самой доке по этой функции сказано об этом крайне невнятно.

Дело в том, что если мы запускаем эту функцию, что бы собрать имена файлов в каком то каталоге, и среди файлов находится хотя бы один у которого требования к привилегиям выше чем у приложения, то GetFiles просто вывалится с невнятным исключением и ни какого списка не будет. Тоже самое касается и привилегий подкаталогов, в режиме SearchOption.AllDirectories.

Так вот, вопрос состоит в том, чем заменить GetFiles, что бы она не падала, как девушка с пониженной социальной ответственностью, вверх ногами, при встрече с более высокими привилегиями, а просто их обходила, и предоставляла список того, к чему есть доступ.

Как то не хочется возвращаться к функциям FindFirst\FindNext\FindClose, да и не уверен я, что эти дремучии функции нормально работают с привилегиями. Или работают?

Правду сказать, ещё не смотрел на Directory.EnumerateFiles, может она поможет?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.08.2018, 15:01
Ответы с готовыми решениями:

Directory.GetFiles
Проблема в следующем: с помощью Directory.GetFiles я хочу достать с папки файлы нужного типа, предположим .doc файлы. Вот код: ...

Directory.GetFiles()
Доброго времени суток :) Меня интересует как заставить Directory.GetFiles() выбирать несколько форматов, а не 1? Ну как взять 1 я...

Фильтры Directory.GetFiles
Здравствуйте, Хочу получить количество файлов в папке типа *.csv и *xlsx. В моем коде я могу получить только одного вида: int...

34
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
10.08.2018, 20:40
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от BrodiagaNG Посмотреть сообщение
Речь идет только о функции без параметров
Могу ошибаться, но без параметров по моему любой другой метод получения файлов тоже никакие исключения не выбрасывает если к указанной папке есть доступ.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
10.08.2018, 20:41
Someone007, все стандартные методы поиска файлов/каталогоа ведут себя одинаково в плане исключений. Аргументы на это не никак не влияют.
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
10.08.2018, 21:19  [ТС]
Разобрался, путем тупого просматривания двух списков, паочка "C:\Windows\Installer" не видна в проводнике, а в списке она появляется. Владелец у неё "BUILTIN\Администраторы", - хз важно ли это.

Добавлено через 2 минуты
Цитата Сообщение от OwenGlendower Посмотреть сообщение
То что окно называется "metadata view" не означает что вся информация в нем взята из метаданных. Информация об исключениях в метаданных не хранится. Она берется из xml комментариев.
Вот ведь! - и тут нас пытаются обмануть!

Цитата Сообщение от OwenGlendower Посмотреть сообщение
Потому что List<T> реализует IEnumerable<T> и значит "совместим" с LINQ без лишних телодвижений. В отличие от ...
Аа, понятно, так то да.

Добавлено через 34 минуты
Цитата Сообщение от Someone007 Посмотреть сообщение
Могу ошибаться, но без параметров по моему любой другой метод получения файлов тоже никакие исключения не выбрасывает если к указанной папке есть доступ.
У майкрософт есть специальная статья по этому поводу, последняя редакция 2015 года, где сказано

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// First, process all the files directly under this folder
try
{
     files = root.GetFiles("*.*");
}
// This is thrown if even one of the files requires permissions greater
// than the application provides.
catch (UnauthorizedAccessException e)
{
// This code just writes out the message and continues to recurse.
// You may decide to do something different here. For example, you
// can try to elevate your privileges and access the file again.
    log.Add(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
    Console.WriteLine(e.Message);
}
Не могу проверить, так как подходящих файлов нет.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
10.08.2018, 21:51
У меня ни GetFiles, ни GetFileSystemInfos не кидают исключения при получении файлов из папки к которой есть доступ, даже если к какому-то файлу, находящемуся в папке закрыт доступ.

Что подтверждает слова сказанные выше
Цитата Сообщение от OwenGlendower Посмотреть сообщение
все стандартные методы поиска файлов/каталогоа ведут себя одинаково в плане исключений
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
10.08.2018, 23:56  [ТС]
Значит так, у меня обновленные net разных версий, и вплоть до 2.0 GetFiles отрабатывает без ошибок, когда он без параметров, или в параметре указано SearchOption.TopDirectoryOnly.

То есть, зря целый день мозг морщил.

С другой стороны, возможно на другой операционке, с другой битностью, с другой версией .net всё не так отлично обстоит, не зря же майкрософт пишет об этой ошибке.

Кроме того, на стековерфлов кажется, были таки вопросы от людей, какого мол хера.

Прогнал у себя всю директорию виндовс, примерно 110К - ни единого прерывания. Но у меня пользователь с правами админа. Короче, не могу толком протестировать.

Добавлено через 1 час 32 минуты
В общем, идея честно подсмотренная у майкрософта, чуть-чуть подрихтовал только. Сам алгоритм мне нравится, остальные материалы в сети, по сравнению с этим, выглядят как поделки. Работает довольно шустро, хотя конечно AddRange не совсем эффективны, много раз одно и то же сливается, но зато текст небольшой и понятный. Exception выдает только некоторые, в основном связанные с корректностью dirPath и полностью проходит по всем доступным по привилегиям папкам. Как раз то что мне нужно было. Всем спасибо, кто участвовал в обсуждении, без вас бы ничего не получилось.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        public static List<string> GetFilesRecursed(string dirPath, string searchPattern)
        {
            var result = new List<string>();
            string[] files = null;
 
            try
            {
                files = Directory.GetFiles(dirPath, searchPattern);
            }
            catch (UnauthorizedAccessException) {}
            catch (DirectoryNotFoundException) {}
 
            if (files != null)
            {
                foreach (var file in files)
                    result.Add(file);
 
                string[] subDirs = Directory.GetDirectories(dirPath);
 
                foreach (var subDir in subDirs)
                    result.AddRange(GetFilesRecursed(subDir, searchPattern));
            }
 
            return result;
        }
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
10.08.2018, 23:58
BrodiagaNG, комментарий про единственный файл ()
Цитата Сообщение от BrodiagaNG Посмотреть сообщение
В общем, идея честно подсмотренная у майкрософта, чуть-чуть подрихтовал только.
Мне больше нравится вариант без рекурсии.
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
11.08.2018, 00:12  [ТС]
Не спорю, - кому что нравится, тут дело вкуса.

Кстати, можно ведь и так записать

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        public static List<string> GetFilesRecursed(string dirPath, string searchPattern)
        {
            var result = new List<string>();
            string[] files = null;
            try { files = Directory.GetFiles(dirPath, searchPattern); }
            catch (UnauthorizedAccessException) {}
            catch (DirectoryNotFoundException) {}
            if (files != null) {
                foreach (var file in files) result.Add(file);
                string[] subDirs = Directory.GetDirectories(dirPath);
                foreach (var subDir in subDirs) result.AddRange(GetFilesRecursed(subDir, searchPattern)); }
           return result;
        }
Собственно, мне сам поиск может и не так сильно нужен, а больше нужен был алгоритм поиска в который легко можно было встроить команды Wow64EnableWow64FsRedirection(). Здесь легко и понятно где именно их поставить. По моим прикидкам, их будет всего 1.5.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
11.08.2018, 00:20
Цитата Сообщение от BrodiagaNG Посмотреть сообщение
Кстати, можно ведь и так записать
Это что-то принципиально меняет? Больше пользы будет от замены цикла foreach на один вызов AddRange.
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
11.08.2018, 00:23  [ТС]
Кидайте в комменты, обсудим. (с)
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
11.08.2018, 15:08
BrodiagaNG, хотя бы так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        public static List<string> GetFilesRecursed(string dirPath, string searchPattern)
        {
            var result = new List<string>();
            string[] files = null;
            try {
                files = Directory.GetFiles(dirPath, searchPattern);
                result.AddRange(files);
            }
            catch (UnauthorizedAccessException) {}
            catch (DirectoryNotFoundException) {}
            if (files != null) {
                string[] subDirs = Directory.GetDirectories(dirPath);
                foreach (var subDir in subDirs) result.AddRange(GetFilesRecursed(subDir, searchPattern));
            }
           return result;
        }
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
11.08.2018, 16:38  [ТС]
В принципе да, очевидно нужно поменять foreach (var file in files) result.Add(file); на result.AddRange(files); в скорости это ничего не даст, но облегчит понимание.

И можно result.AddRange(files); переставить в другое место, оно конечно генерит ArgumentNullException, однако до него дело никогда не дойдет. Но само решение спорное, простота понимания ухудшится, надо же будет напрячься, подумать, что там произойдет.

ОК, с точки зрения "красивостей", когда всё хитро связано и работает - да. С точки зрения простоты понимания логики алгоритма - нет.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
11.08.2018, 17:30
Цитата Сообщение от BrodiagaNG Посмотреть сообщение
в скорости это ничего не даст
Уверен? Один вызов вместо N. Одно дополнительное выделение памяти вместо потцениальных наскольких.
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
11.08.2018, 17:56  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Уверен? Один вызов вместо N. Одно дополнительное выделение памяти вместо потцениальных наскольких.
Не, ну если ты ТАК вопрос ставишь, конечно, слить два массива указателей быстрее и приятнее чем впихивать указатели в массив по одному. Но чисто в житейском плане - не заметишь.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18419 / 14350 / 5371
Регистрация: 17.03.2014
Сообщений: 29,033
Записей в блоге: 1
11.08.2018, 18:07
Цитата Сообщение от BrodiagaNG Посмотреть сообщение
если ты ТАК вопрос ставишь, конечно, слить два массива указателей быстрее и приятнее чем впихивать указатели в массив по одному
А как еще ставить вопрос в разговоре о скорости.

Цитата Сообщение от BrodiagaNG Посмотреть сообщение
чисто в житейском плане - не заметишь.
Не уверен. На большом количестве каталогов по моему должна быть заметная разница.
0
0 / 0 / 0
Регистрация: 06.08.2018
Сообщений: 22
11.08.2018, 18:34  [ТС]
Не, я не такой поборник скорости, для меня что 150 что 250 - один хрен! но я понимаю о чем ты пишешь, да.

Лучше, если шаришь в WPF и в форуме (где что лежит) зайди в эту тему https://www.cyberforum.ru/net-... 83558.html - подскажи что нибудь, а?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.08.2018, 18:34

OleDbDataReader, Directory.GetFiles
Здравствуйте! Столкнулся с проблемкой. Может кто увидит ошибку. Есть код: connection.Open(); OleDbDataReader reader =...

Directory.GetFiles - динамический вызов?
Добрый вечер. Не могу понять почему при вызове: Directory.GetFiles(Server.MapPath(&quot;~/Images/&quot; + ViewBag.Id)).Select(n =&gt;...

Как указать несколько шаблонов в searchPattern для Directory.GetFiles()?
Здравствуйте форумчане, возникла проблемка: Есть функция которая вот такая, ошибка отмечена, вопрос как это исправить? public...

Путь в Directory.GetFiles
Пытаюсь указать путь для картинок через Directory.GetFiles Вот код ar.AddRange(Directory.GetFiles(@&quot;C:\Users\Desktop\&quot;,...

Ограничить поиск файлов в Directory.GetFiles до 1000 результатов
Добрый день! Есть папка с огромным количеством подпапок в каждой из которых лежат XML файлы. Количество папок на столько велико, что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru