1

最終的な目標は、txt ファイルに格納されるディレクトリの階層構造を格納する何らかの形式のデータ構造を持つことです。

これまでのところ、次のコードを使用していますが、ディレクトリ、サブディレクトリ、およびファイルの組み合わせに苦労しています。

/// <summary>
/// code based on http://msdn.microsoft.com/en-us/library/bb513869.aspx
/// </summary>
/// <param name="strFolder"></param>
public static void TraverseTree ( string strFolder )
{
  // Data structure to hold names of subfolders to be
  // examined for files.
  Stack<string> dirs = new Stack<string>( 20 );

  if ( !System.IO.Directory.Exists( strFolder ) )
  {
    throw new ArgumentException();
  }
  dirs.Push( strFolder );

  while ( dirs.Count > 0 )
  {
    string currentDir = dirs.Pop();
    string[] subDirs;
    try
    {
      subDirs = System.IO.Directory.GetDirectories( currentDir );
    }

    catch ( UnauthorizedAccessException e )
    {
      MessageBox.Show( "Error: " + e.Message );
      continue;
    }
    catch ( System.IO.DirectoryNotFoundException e )
    {
      MessageBox.Show( "Error: " +  e.Message );
      continue;
    }

    string[] files = null;
    try
    {
      files = System.IO.Directory.GetFiles( currentDir );
    }

    catch ( UnauthorizedAccessException e )
    {
      MessageBox.Show( "Error: " +  e.Message );
      continue;
    }

    catch ( System.IO.DirectoryNotFoundException e )
    {
      MessageBox.Show( "Error: " + e.Message );
      continue;
    }
    // Perform the required action on each file here.
    // Modify this block to perform your required task.
    /*
    foreach ( string file in files )
    {
      try
      {
        // Perform whatever action is required in your scenario.
        System.IO.FileInfo fi = new System.IO.FileInfo( file );
        Console.WriteLine( "{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime );
      }
      catch ( System.IO.FileNotFoundException e )
      {
        // If file was deleted by a separate application
        //  or thread since the call to TraverseTree()
        // then just continue.
        MessageBox.Show( "Error: " +  e.Message );
        continue;
      }
    } 
    */

    // Push the subdirectories onto the stack for traversal.
    // This could also be done before handing the files.
    foreach ( string str in subDirs )
      dirs.Push( str );

    foreach ( string str in files )
      MessageBox.Show( str );
  }
4

5 に答える 5

8

複合アイテムがフォルダである一種の複合パターンを使用できます。

ターゲット フォルダのツリー構造を構築するサンプル コードを次に示します。これは再帰的に動作し、メモリを少し消費しますが、その単純さはそれだけの価値があります。

class TreeItem
{
    public string FolderName;
    public List<TreeItem> SubFolders = new List<TreeItem>();
    public string[] Files;
}

class Program
{

    private static TreeItem FileTree(string rootFolder){
        var item = new TreeItem();
        item.FolderName = rootFolder;
        item.Files = System.IO.Directory.GetFiles(rootFolder);

        foreach(var folder in System.IO.Directory.GetDirectories(rootFolder))
        {
            item.SubFolders.Add(FileTree(folder));
        }
        return item;
    }

    //Traversal algorithm
    private static void PrintComposite(TreeItem node, int ident)
    {
        var dirName = System.IO.Path.GetFileName(node.FolderName);
        Console.WriteLine(@"{0}{1}", new string('-', ident), dirName);
        foreach(var subNode in node.SubFolders)
        {
            PrintComposite(subNode, ident + 1);
        }
    }

    public static void Main(string[] args)
    {
        var tree = FileTree(@"D:\Games");
        PrintComposite(tree,0);
    }   
}
于 2010-04-28T19:10:55.143 に答える
1

一つには、より多くのオブジェクトを作成する必要があると思います。DirectoryElementInterface インターフェイスまたは抽象クラス、DirectoryElement オブジェクト、および DirectoryElementInterface を実装する FileElement オブジェクト。ここで、スタックを使用して階層を反復処理するのではなく、 を作成しますDirectoryElementInterface root = new DirectoryElement(nameOfNode)。次に、 getFiles のすべてのファイルに対して、次のようなことを行いますroot.addElement(new FileElement(filename));。addElement は、DirectoryElement 内のリストに追加する必要があります。ディレクトリについても同様に行います。OK、これで 1 つのレベルを作成できます。

次に、反復ステップです。作成したばかりのルーチンを使用してroot、パラメーターを作成します。任意の名前を付けることができますが、この説明では、この新しいルーチン addDirectoryInformation と呼びます。メインは、ルートの作成と、ルートを渡す addDirectoryInformation の呼び出しです。反復するには、現在入力されているルートに要素のリストを要求し、リストに対して foreach を実行し、ディレクトリである各要素に対して addDirectoryInformation を呼び出す必要があります。それが機能したら、ループを addDirectoryInformation の最後に移動します。追加するすべてのディレクトリは、すべての子を再帰的に追加します。

適切な再帰プログラムについてもう 1 つ。いつ再帰を停止するかを知っておく必要があります。この場合は簡単です。リストにディレクトリがない場合、addDirectoryInformation は呼び出されません。これで完了です。

于 2010-04-28T19:45:51.037 に答える
0

先週、同様のことを行ったコースを受講しました。出力はコンソールに出力されましたが、.txt ファイルにストリームライトできない理由はありません。

システムを使用する; System.Collections.Generic の使用; System.Linq を使用します。System.Text を使用します。

名前空間 ShowDirectory { class Program { static void Main(string[] args) { Console.WriteLine("このプログラムは、ディレクトリ内のすべてのファイルを一覧表示します。"); System.IO.DirectoryInfo dir = 新しい System.IO.DirectoryInfo(@"C:\"); foreach (dir.GetFiles(" . ") 内の System.IO.FileInfo ファイル) { Console.WriteLine("{0}, {1}", file.Name, file.Length); } Console.ReadLine(); } } }

于 2010-05-26T16:13:56.177 に答える
0

http://weblogs.asp.net/israelio/archive/2004/06/23/162913.aspxに基づくコードを使用して動作させました

// How much deep to scan. (of course you can also pass it to the method)
const int HowDeepToScan=20;

public static void ProcessDir ( string dirName, int recursionLvl, string strFileName)
{

  string tabs = new String( '-', recursionLvl );

  if ( recursionLvl<=HowDeepToScan )
  {
    // Process the list of files found in the directory. 
    string [] fileEntries = Directory.GetFiles( dirName );
    TextWriter tw = new StreamWriter( strFileName, true );
    tw.WriteLine( tabs + "<a href=\" " +  System.IO.Path.GetFullPath( dirName ) + "\">" + System.IO.Path.GetFileName( dirName ) + "</a><br />" );
    foreach ( string fileName in fileEntries )
    {
      // do something with fileName

      tw.WriteLine( tabs + "<a href=\" " +  System.IO.Path.GetFullPath( fileName ) + "\">" + System.IO.Path.GetFileName( fileName ) + "</a><br />" );

    }
    tw.Close();

    // Recurse into subdirectories of this directory.
    string [] subdirEntries = Directory.GetDirectories( dirName );
    foreach ( string subdir in subdirEntries )
      // Do not iterate through reparse points
      if ( ( File.GetAttributes( subdir ) &
        FileAttributes.ReparsePoint ) !=
            FileAttributes.ReparsePoint )

        ProcessDir( subdir, recursionLvl+1, strFileName );

  }
}

出力

<a href=" C:\code">code</a><br />
<a href=" C:\code\group.zip">FluentPath (1).zip</a><br />
<a href=" C:\code\index.html">index.html</a><br />
于 2010-04-29T12:46:41.453 に答える