0

私は私が克服できないように見えるこの問題を抱えています。すべてのディレクトリとサブディレクトリを一覧表示しようとしています。これは私がこれまでのコードで持っているものです:

String[] Folders;
            String[] Files;
            path = Server.MapPath("/");

            DirectoryInfo dir = new DirectoryInfo(path);
            Folders = Directory.GetDirectories(path);

            try
            {
                FolderListing.Append("<ul id=\"FolderList\">");

                for (int x = 0; x < Folders.Length; x++ )
                {
                    DirectoryInfo folder = new DirectoryInfo(Folders[x]);

                    FolderListing.Append("<li>").Append(folder.Name).Append("</li>");
                    CheckSubdirectories(Folders[x]);
                }



                FolderListing.Append("</ul>");
                FolderList.Text = FolderListing.ToString();
            }
            catch (Exception exc) //Module failed to load
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }
        private void CheckSubdirectories(string currentpath)
        {
           String[] subfolders = Directory.GetDirectories(currentpath);
           if (subfolders.Length != 0)
           {
               FolderListing.Append("<ul id=\"SubFolderList\">");
           }
            for (int x = 0; x < subfolders.Length; x++ )
            {
               DirectoryInfo sfolder = new DirectoryInfo(subfolders[x]);
               FolderListing.Append("<li>").Append(sfolder.Name).Append("</li>");
            }
            if (subfolders.Length != 0)
            {
                FolderListing.Append("</ul>");
            }
            path = currentpath.ToString();
        }

最終結果を次のようにしたいと思います:

<ul>
    <li>admin</li>
    <ul>
        <li>Containers</li>
        <li>ControlPanel</li>
        <li>Menus</li>
        <ul>
            <li>etc etc</li>
        </ul>
    </ul>
</ul>

誰かが私を助けることができるならお願いします

4

3 に答える 3

1

これは機能します:

Func<DirectoryInfo, XElement[]> getDirectories = null;
getDirectories = di =>
    (new []
    {
        new XElement("li", di.Name),
        di.GetDirectories().Any()
            ? new XElement("ul",
                from cdi in di.GetDirectories()
                select getDirectories(cdi))
            : null,
    })
        .Where(x => x != null)
        .ToArray();

var xml = new XElement("ul",
    getDirectories(
        new DirectoryInfo(@"E:\Install\_.NET")));

私のサンプルディレクトリから、次の出力が得られました。

<ul>
  <li>_.NET</li>
  <ul>
    <li>3DCollaborator</li>
    <li>MercurialVSSProvider</li>
    <li>MongoDB</li>
    <li>sqlite</li>
    <ul>
      <li>sqlite-netFx35-binary-bundle-Win32-2008-1.0.74.0</li>
      <li>sqlite-netFx35-binary-Win32-2008-1.0.74.0</li>
      <li>sqlite-netFx40-binary-Win32-2010-1.0.74.0</li>
    </ul>
  </ul>
</ul>
于 2012-07-16T12:32:46.737 に答える
0

再帰的アプローチを使用して問題を解決できます。任意の深さでネストされているサブディレクトリを一覧表示するには、それ自体を呼び出すメソッドが必要です。

public ListDirectory (DirectoryInfo dir)
{
     //TODO: Output the directory info here.
     foreach (DirectoryInfo subdir in dir.Directories) {
         ListDirectory(subdir);
     }
     foreach (FileInfo file in dir.Files) {
         //TODO: Output the file info here.
     }
}

リストはHTMLでは次のようになります。<li>サブディレクトリはネストされた全体を囲む必要があることに注意してください<ul>

<ul> 
    <li>subdirectory item 1
        <ul> 
            <li>file 1 in subdirectory</li> 
            <li>file 2 in subdirectory</li> 
        </ul> 
    </li> 
    <li>subdirectory item 2
        <ul> 
            <li>sub-subdirectory item
                <ul> 
                    <li>file 1 in sub-subdirectory</li> 
                    <li>file 2 in sub-subdirectory</li> 
                </ul> 
            </li> 
            <li>file 1 in subdirectory</li> 
            <li>file 2 in subdirectory</li> 
        </ul> 
    </li> 
    <li>file item 1</li> 
    <li>file item 2</li> 
</ul>

これにより、次の出力が生成されます。

  • サブディレクトリアイテム1
    • サブディレクトリのファイル1
    • サブディレクトリのファイル2
  • サブディレクトリアイテム2
    • サブサブディレクトリアイテム
      • サブサブディレクトリのファイル1
      • サブサブディレクトリのファイル2
    • サブディレクトリのファイル1
    • サブディレクトリのファイル2
  • ファイルアイテム1
  • ファイルアイテム2

この情報を使用して、上記の方法を(擬似コードで)改良できます。

public ListDirectory (DirectoryInfo dir)
{
     Output("<li>");    Output(dir.Name);
         if (dir.Directories.Count > 0 || dir.Files.Count > 0) {
             Output("<ul>");
             foreach (DirectoryInfo subdir in dir.Directories) {
                 ListDirectory(subdir);
             }
             foreach (FileInfo file in dir.Files) {
                 Output("<li>");  Output(file.Name);  Output("</li>");
             }
             Output("</ul>");
         }
     Output("</li>");
}

<ul> </ul>また、すべてをペアで囲む必要があります。また、上記のコードのように、ルートディレクトリを1つだけではなく、ファイルとディレクトリを一覧表示するために、最初のレベルで少し異なるスキームを使用することもできます。

于 2012-07-16T12:24:33.110 に答える
0

この再帰的な方法が役立つことを願っています:

void ListDirectories(string path, StringBuilder sb)
{
    var directories = Directory.GetDirectories(path);
    if (directories.Any())
    {
        sb.AppendLine("<ul>");
        foreach (var directory in directories)
        {
            var di = new DirectoryInfo(directory);
            sb.AppendFormat("<li>{0}</li>", di.Name);
            sb.AppendLine();
            ListDirectories(directory, sb);
        }
        sb.AppendLine("</ul>");
    }
}

これを呼び出すには、のインスタンスを作成StringBuilderし、メソッドへのパスと一緒に送信します。

var sb = new StringBuilder();
ListDirectories(Server.MapPath("/"), sb);
于 2012-07-16T12:34:42.673 に答える