Список всех папок и файлов для глубины x

#c# #.net #visual-studio-2010 #file #directory

#c# #.net #visual-studio-2010 #файл #каталог

Вопрос:

Я хочу иметь список всех папок и файлов для x глубины.

Если x равно 2, то у меня будет информация обо всех папках и файлах из первой папки, а также обо всех папках и файлах из папок в первой папке.

Как это сделать?

Ответ №1:

Этот код будет делать то, что делают другие ответы, но также вернет имена папок (поскольку это, по-видимому, является частью того, что вы спрашиваете). Для этого потребуется .Net 4.0. Если вы хотите отслеживать, какие папки, а какие файлы, вы могли бы вернуть кортеж, содержащий список файлов и список папок.

 List<string> GetFilesAndFolders(string root, int depth)
{
    var list = new List<string>();
    foreach(var directory in Directory.EnumerateDirectories(root))
    {
        list.Add(directory);
        if (depth > 0)
        {
            list.AddRange(GetFilesAndFolders(directory, depth-1));
        }
    }

    list.AddRange(Directory.EnumerateFiles(root));

    return list;
}
  

РЕДАКТИРОВАТЬ: Код, который разделяет папки и файлы

 Tuple<List<string>,List<string>> GetFilesAndFolders(string root, int depth)
{
    var folders = new List<string>();
    var files = new List<string>();
    foreach(var directory in Directory.EnumerateDirectories(root))
    {
        folders.Add(directory);
        if (depth > 0)
        {
                var result = GetFilesAndFolders(directory, depth-1);
                folders.AddRange(result.Item1);
                files.AddRange(result.Item2);
        }
    }

    files.AddRange(Directory.EnumerateFiles(root));

    return new Tuple<List<string>,List<string>>(folders, files);
}
  

Комментарии:

1. И «выше» здесь не является хорошим механизмом ссылки. Смотрите вкладки сортировки.

2. Что касается сортировки, то ее достаточно легко добавить или вернуть несколько списков, в вопросе говорилось о списке папок и files…so Я написал это таким образом. Что касается приведенной выше ссылки, вы правы, спешили и не продумали это, отредактируем

Ответ №2:

Я чувствую, что это было решено раньше. По сути, то, что вы хотите сделать, это спросить текущий файл, является ли он каталогом, если true и x еще не исчерпан, захватить подкаталоги этого файла. Кроме того, вам необходимо проверить, присутствуют ли файлы в этом каталоге, и также извлечь их.

Ответ №3:

если вам нужны только имена файлов, вы можете сделать это рекурсивным методом. что-то вроде этого: (нет гарантии полной корректности, я пишу без компилятора)

     public static List<String> GetSubfoldersAndFiles(DirectoryInfo di, int deep)
    {
       List<string> myContent = new List<string>();
       foreach(FileInfo fi in di.GetFiles())
       {
          myContent.Add(fi.FullName);
       }

       if(deep > 0)
       {
          foreach(DirectoryInfo subDi in di.GetDirectories())
          {
              myContent.AddRange(GetSubfoldersAndFiles(subDi, deep - 1).ToArray());
          }
       }

       return myContent;
    }
  

и вызов был бы таким:

 List<string> content = GetSubfoldersAndFiles(new DirectoryInfo(@"c:", 3));
  

Комментарии:

1. На самом деле ваш --deep приведет к сбою. Еще одна причина избегать и -- , после или до.

2. это не так, —deep сделает именно то, от чего я ожидаю. почему это должно завершиться неудачей?

3. Вам нужно переместить вызов —deep за пределы foreach, иначе вы будете неправильно искать подкаталоги, если только там нет только 1 (просто представьте, что вызываете его в качестве списка примеров с глубиной 3, а в верхней папке есть 3 вложенные папки, к тому времени, когда вы доберетесь до второй вложенной папки, вы будете искать в ней только глубину 1, в третьей вы вообще не будете выполнять рекурсивный поиск)

4. но, по крайней мере, этот код работает и с 2.0, и ДА, в рабочей версии grmbl все еще есть сервер win2k …;-)

Ответ №4:

Все вложенные папки

 public List<string> listDir(string pPath)
        {
            List<string> dirList = new List<string>();
            listDir(pPath, dirList);
            return dirList;
        }
private void listDir(string pPath, List<string> pList)
        {
                string[] loDirs = System.IO.Directory.GetDirectories(pPath);
                foreach (string loDir in loDirs)
                {
                    pList.Add(loDir);
                    listDir(loDir, pList);
                }
        }
  

Ответ №5:

Расширение ответа @pstrjds

 private static IReadOnlyList<string> SearchFiles(string root, string pattern = "*", int depth = 1, params string[] exceptFolders)
{
    var files = Directory
        .EnumerateDirectories(root)
        .Where(it => !exceptFolders.Contains(Path.GetRelativePath(root, it)) amp;amp; depth > 0)
        .SelectMany(it => SearchFiles(it, pattern, depth - 1, exceptFolders))
        .ToList();

    files.AddRange(Directory.EnumerateFiles(root, pattern));

    return files;
}
  

Комментарии:

1. Path.getRelativePath(root, it), похоже, не существует как часть Path. Я просто удалил его и аргумент exceptFolders, поскольку он мне не был нужен.