как мне перечислить все возможные каталоги и пути к подпапкам, игнорируя файлы - PullRequest
0 голосов
/ 23 декабря 2011

Я хочу все возможные пути к папкам из корня, игнорируя все пути, которые заканчиваются только файлом. getdirectories не перечисляет все возможные пути.

Например: root: папки a и b

      path a - c
      path a - c - d
      path a - c - x

      path b - e
      path b - e - f
      path b - e - g

Ответы [ 8 ]

2 голосов
/ 23 декабря 2011

Вам нужно рекурсивно повторять и посещать каждую папку.См. Пример в этом MSDN artcile .

1 голос
/ 23 декабря 2011

Это позаботится о DirectoryNotFoundException и UnauthorizedAccessException:

IEnumerable<string> GetFoldersRecursive(string directory)
{
    var result = new List<string>();
    var stack = new Stack<string>();
    stack.Push(directory);

    while (stack.Count > 0)
    {
        var dir = stack.Pop();

        try
        {
            result.AddRange(Directory.GetDirectories(dir, "*.*"));
            foreach (string dn in Directory.GetDirectories(dir))
            {
                stack.Push(dn);
            }
        }
        catch
        {
        }
    }

    return result;
}

Обратите внимание, что это, вероятно, будет не так эффективно, как другие методы из-за блока try / catch.

* Отказ от ответственности: я не писал этот код изначально (нашел его на SO!), Я только изменил его, чтобы соответствовать потребности.

1 голос
/ 23 декабря 2011

Наконец-то конвертировал мою версию VB.NET в C #:

namespace ExtensionMethods
{
    public static class DirectoryExtensions
    {
        public static List<DirectoryInfo> GetSubFolders(this DirectoryInfo rootFolder)
        {
            if (rootFolder == null)
            {
                throw new ArgumentException("Root-Folder must not be null!", "rootFolder");
            }

            List<DirectoryInfo> subFolders = new List<DirectoryInfo>();
            AddSubFoldersRecursively(rootFolder, ref subFolders);
            return subFolders;
        }

        private static void AddSubFoldersRecursively(DirectoryInfo rootFolder, ref List<DirectoryInfo> allFolders)
        {
            try
            {
                allFolders.Add(rootFolder);
                foreach (DirectoryInfo subFolder in rootFolder.GetDirectories())
                {
                    AddSubFoldersRecursively(subFolder, ref allFolders);
                }
            }
            catch (UnauthorizedAccessException exUnauthorized)
            {
                // go on 
            }
            catch (DirectoryNotFoundException exNotFound)
            {
                // go on 
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}

Если кто-то заинтересован в версии VB.NET:

Public Module DirectoryExtensions
    <Runtime.CompilerServices.Extension()>
    Public Function GetSubFolders(ByVal rootFolder As DirectoryInfo) As List(Of DirectoryInfo)
        If rootFolder Is Nothing Then
            Throw New ArgumentException("Root-Folder must not be null!", "rootFolder")
        End If

        Dim subFolders As New List(Of DirectoryInfo)
        AddSubFoldersRecursively(rootFolder, subFolders)
        Return subFolders
    End Function

    Private Sub AddSubFoldersRecursively(rootFolder As DirectoryInfo, ByRef allFolders As List(Of DirectoryInfo))
        Try
            allFolders.Add(rootFolder)
            For Each subFolder In rootFolder.GetDirectories
                AddSubFoldersRecursively(subFolder, allFolders)
            Next
       Catch exUnauthorized As UnauthorizedAccessException
           ' go on '
       Catch exNotFound As DirectoryNotFoundException
           ' go on '
       Catch ex As Exception
           Throw
       End Try
    End Sub
End Module

Проверено с:

Dim result = Me.FolderBrowserDialog1.ShowDialog()
If result = Windows.Forms.DialogResult.OK Then
     Dim rootPath = Me.FolderBrowserDialog1.SelectedPath
     Dim rootFolder = New DirectoryInfo(rootPath)
     Dim query = From folder In rootFolder.GetSubFolders()
            Select folder.FullName
     If query.Any Then
          Me.ListBox1.Items.AddRange(query.ToArray)
     End If
 End If
1 голос
/ 23 декабря 2011
private void ListAllDirectories(string root)
{
    DirectoryInfo dr = new DirectoryInfo(root);
                Console.WriteLine(dr.FullName);
                var directories = dr.GetDirectories();
                foreach (var directory in directories)
                {
                    try
                    {
                        ListAllDirectories(directory.FullName);

                    }

                    catch
                    {
                        continue;
                    }

                }
}

Catch для обработки несанкционированных исключений и т. Д., Только для начала.

1 голос
/ 23 декабря 2011

Если вам нужно просмотреть много каталогов и вам нужно пропустить каталоги, к которым у пользователя нет доступа, лучше всего ставить EnumerateDirectories :

        // LINQ query.
        var dirs = from dir in 
                 Directory.EnumerateDirectories("C:\", "*",                         SearchOption.AllDirectories)
                   select dir;

        // Show results.
        foreach (var dir in dirs)
        {
            // Do something with the dir
        }
1 голос
/ 23 декабря 2011

Этот подход решает проблему, упомянутую Стрилло в его комментарии к ответу Ника.Это также более эффективно.

DirectoryInfo info = new DirectoryInfo(yourRoot);

foreach (var d in info.EnumerateDirectories("*",SearchOption.AllDirectories))
{
    Console.WriteLine(d.FullName);
}

Прочитайте раздел «Примечания» на этом документе MSDN .

1 голос
/ 23 декабря 2011

Нет причин писать рекурсивную функцию.Вы можете просто использовать одну из перегрузок.

oRoot.GetDirectories("*", SearchOption.AllDirectories);
1 голос
/ 23 декабря 2011

Directory.GetDirectories () возвращает все непосредственные дочерние элементы.

Вам необходимо сделать вызов рекурсивным.Псевдокод ниже - у меня нет доступа к компьютеру в данный момент.

// Output All Leaf Nodes From Root
EnumerateDirectory(@"c:\");

public void EnumerateDirectory(string baseDirectory)
{
    if( Directory.GetDirectories(baseDirectory).Count == 0 )
    {
         // This is an end, leaf node.
         Output("This is a leaf node.");
         return;
    }

    foreach(var directory in Directory.GetDirectories(baseDirectory) )
    {
          EnumerateDirectory(directory);
          return;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...