Вопрос по file, c#, directory, exception – Получение файлов рекурсивно: пропустить файлы / каталоги, которые не могут быть прочитаны?

6

Я хочу получить все файлы в каталоге в массиве (включая файлы в подпапках)

string[] filePaths = Directory.GetFiles(@"c:\",SearchOption.AllDirectories);     

Проблема в следующем: если выдается исключение, вся команда останавливается. Есть ли лучший способ сделать это так, чтобы, если папка не была доступна, она просто пропустила ее?

Судя по@"c:\"Я думаю, что он спрашивает, может ли вызов метода завершить свою работу и получить все каталоги, к которым предоставляется доступ. hmqcnoesy
попробуйте поймать, может быть? Gonzalo.-
Не перегруженныйGetFiles method shows an example of recursing manually и это не будет трудно добавить обработку исключений .. Яassuming проблема возникает из-за невозможностиread подкаталоги; и чтоDirectory.GetFiles(.., without_recursive_search) будет работать как все или ничего дляspecific directory как и ожидалось. user166390
(Хотя этот пример упрощен: результат только побочный эффект, и «плохие вещи» будут иметь место, если существуют рекурсивные соединения или ссылки в каталогах ...) user166390
@hmqcnoesy Точно. Wilson

Ваш Ответ

3   ответа
-1

DirectoryInfo directory = new DirectoryInfo(@"c:\");
        DirectoryInfo[] folders = directory.GetDirectories("*", SearchOption.AllDirectories);

        List<string> files = new List<string>();
        foreach (DirectoryInfo info in folders)
        {
            foreach (FileInfo file in info.GetFiles())
            {
                files.Add(file.Name);
            }
        }
Что происходит, если есть папкаC:\NoPermissionsToRead?
6

вероятно, придется немного больше набрать текст самостоятельно и написать обходчик каталогов, как этот:

    public static string[] FindAllFiles(string rootDir) {
        var pathsToSearch = new Queue<string>();
        var foundFiles = new List<string>();

        pathsToSearch.Enqueue(rootDir);

        while (pathsToSearch.Count > 0) {
            var dir = pathsToSearch.Dequeue();

            try {
                var files = Directory.GetFiles(dir);
                foreach (var file in Directory.GetFiles(dir)) {
                    foundFiles.Add(file);
                }

                foreach (var subDir in Directory.GetDirectories(dir)) {
                    pathsToSearch.Enqueue(subDir);
                }

            } catch (Exception /* TODO: catch correct exception */) {
                // Swallow.  Gulp!
            }
        }

        return foundFiles.ToArray();
    }
Это сработало отлично! Это намного медленнее, чем встроенная версия, но, конечно, они не обрабатывают файлы без аутентификации.
@pst Согласен с пунктами 2 и 3 (ToArray должен был произвести то же самоеstring[] как в вопросе и не является обязательным), но имеет ли смысл пункт 1, если все доступные подкаталоги необходимо обойти?
Примечания: 1) Это реализация BFS, а не DFS. 2) Это не касается рекурсивных структур (точка соединения или жесткие / программные ссылки в NTFS). 3)ToArray кажется глупым
@ikh Я вообще не говорю, что это плохо, просто так :) Это разница между обходами в порядке:C:\a\ C:\b\ C:\a\aa\  (в ширину) иC:\a\ C:\a\aa\ C:\b\  (сначала в глубину). Некоторые могут ожидать другого поведения (DFS), поэтому об этом следует помнить.
-1

        DirectoryInfo dirs = new DirectoryInfo(@"c:\");
        List<string> filenames = (from i in dirs.GetFiles("*", SearchOption.AllDirectories)
                                  select i.Name).ToList();

или имена файлов без расширения:

        DirectoryInfo dirs = new [email protected]"c:\");
        List<string> filenames = (from i in dirs.GetFiles("*", SearchOption.AllDirectories)
                                  select System.IO.Path.GetFileNameWithoutExtension(i.Name)).ToList();
Как это будет действовать / действовать в случаях, когда каталог не может быть прочитан?

Похожие вопросы