DOBON.NET

あるフォルダ以下にあるファイルをすべて取得する

.NET Framework 2.0以降で、Directory.GetFilesメソッドのみを使う

指定したフォルダ以下のすべてのファイルのパスを取得するには、Directory.GetFilesメソッド(System.IO名前空間)を使用します。GetFilesメソッドは3番目のパラメータを省略(あるいは、SearchOption.TopDirectoryOnlyを指定)すると、指定したフォルダにあるファイルしか取得せず、サブフォルダにあるファイルは取得しません。サブフォルダのファイルも含め、すべてのファイルを取得するには、3番目のパラメータにSearchOption.AllDirectoriesを指定します。

以下の例では、フォルダ"C:\test"以下にあるファイルのパスをすべて取得し、リストボックス(ListBox1)に表示しています。

VB.NET
コードを隠すコードを選択
'"C:\test"以下のファイルをすべて取得する
'ワイルドカード"*"は、すべてのファイルを意味する
Dim files As String() = System.IO.Directory.GetFiles( _
    "C:\test", "*", System.IO.SearchOption.AllDirectories)

'ListBox1に結果を表示する
ListBox1.Items.AddRange(files)
C#
コードを隠すコードを選択
//"C:\test"以下のファイルをすべて取得する
//ワイルドカード"*"は、すべてのファイルを意味する
string[] files = System.IO.Directory.GetFiles(
    @"C:\test", "*", System.IO.SearchOption.AllDirectories);

//ListBox1に結果を表示する
ListBox1.Items.AddRange(files);

補足:VB.NETではMy.Computer.FileSystem.GetFilesメソッドでも同様のことができます。

補足:Directory.GetFileSystemEntriesメソッドを使用すると、指定したフォルダ以下にあるフォルダとファイルの両方を取得することができます。

また、DirectoryInfo.GetFilesメソッドを使っても同じことができます。戻り値は、FileInfoの配列です。

VB.NET
コードを隠すコードを選択
'"C:\test"以下の".txt"ファイルをすべて取得する
Dim di As New System.IO.DirectoryInfo("C:\test")
Dim files As System.IO.FileInfo() = _
    di.GetFiles("*.txt", System.IO.SearchOption.AllDirectories)

'ListBox1に結果を表示する
For Each f As System.IO.FileInfo In files
    ListBox1.Items.Add(f.FullName)
Next
C#
コードを隠すコードを選択
//"C:\test"以下の".txt"ファイルをすべて取得する
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@"C:\test");
System.IO.FileInfo[] files =
    di.GetFiles("*.txt", System.IO.SearchOption.AllDirectories);

//ListBox1に結果を表示する
foreach (System.IO.FileInfo f in files)
{
    ListBox1.Items.Add(f.FullName);
}

.NET Framework 4.0以降で、Directory.EnumerateFilesメソッドを使う

.NET Framework 4.0からは、Directory.EnumerateFilesメソッドを使っても同様のことができます。EnumerateFilesメソッドの戻り値は、IEnumerable<String>です。

ファイルを一度にすべて取得する場合は、GetFilesメソッドと比べてEnumerateFilesメソッドのメリットはほとんどありません。しかし、ファイルを1つずつ列挙する場合は、メリットがあります。GetFilesメソッドは、必ずすべてのファイルを検索し終えてから結果を返すため、はじめの1つのファイルを取得するだけであっても長時間かかってしまう恐れがあります。それに対してEnumerateFilesメソッドは、ファイルが見つかればすぐに返しますので、ファイルの列挙で長時間ブロックされることがありません。

以下の例では、フォルダ"C:\test"以下にあるファイルをすべて列挙して、1つずつListBox1に追加しています。

VB.NET
コードを隠すコードを選択
'"C:\test"以下のファイルをすべて取得する
Dim files As IEnumerable(Of String) = _
    System.IO.Directory.EnumerateFiles( _
        "C:\test", "*", System.IO.SearchOption.AllDirectories)

'ファイルを列挙する
For Each f As String In files
    ListBox1.Items.Add(f)
Next
C#
コードを隠すコードを選択
//"C:\test"以下のファイルをすべて取得する
IEnumerable<string> files =
    System.IO.Directory.EnumerateFiles(
        @"C:\test", "*", System.IO.SearchOption.AllDirectories);

//ファイルを列挙する
foreach (string f in files)
{
    ListBox1.Items.Add(f);
}

補足:EnumerateFileSystemEntriesメソッドを使用すると、あるフォルダ以下にあるフォルダとファイルの両方を取得することができます。

また、DirectoryInfo.EnumerateFilesメソッドを使っても同じことができます。このメソッドの戻り値は、IEnumerable<FileInfo>です。

VB.NET
コードを隠すコードを選択
'"C:\test"以下のファイルをすべて取得する
Dim di As New System.IO.DirectoryInfo("C:\test")
Dim files As IEnumerable(Of System.IO.FileInfo) = _
    di.EnumerateFiles("*", System.IO.SearchOption.AllDirectories)

'ファイルを列挙する
For Each f As System.IO.FileInfo In files
    ListBox1.Items.Add(f.FullName)
Next
C#
コードを隠すコードを選択
//"C:\test"以下のファイルをすべて取得する
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@"C:\test");
IEnumerable<System.IO.FileInfo> files =
    di.EnumerateFiles("*", System.IO.SearchOption.AllDirectories);

//ファイルを列挙する
foreach (System.IO.FileInfo f in files)
{
    ListBox1.Items.Add(f.FullName);
}

.NET Framework 1.1以前

.NET Framework 1.1以前では、Directory.GetFilesメソッドに3番目のパラメータがありませんので、サブフォルダのファイルまで取得できません。

例えば次のようなメソッドを作成することで、指定されたフォルダ以下のすべてのファイルを取得することができるようになります。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 指定されたフォルダ以下にあるすべてのファイルを取得する
''' </summary>
''' <param name="folder">ファイルを検索するフォルダ名。</param>
''' <param name="searchPattern">ファイル名検索文字列
''' ワイルドカード指定子(*, ?)を使用する。</param>
''' <param name="files">見つかったファイル名のリスト</param>
Public Sub GetAllFiles(ByVal folder As String, _
        ByVal searchPattern As String, ByRef files As ArrayList)
    'folderにあるファイルを取得する
    Dim fs As String() = _
        System.IO.Directory.GetFiles(folder, searchPattern)
    'ArrayListに追加する
    files.AddRange(fs)

    'folderのサブフォルダを取得する
    Dim ds As String() = System.IO.Directory.GetDirectories(folder)
    'サブフォルダにあるファイルも調べる
    Dim d As String
    For Each d In ds
        GetAllFiles(d, searchPattern, files)
    Next d
End Sub
C#
コードを隠すコードを選択
/// <summary>
/// 指定されたフォルダ以下にあるすべてのファイルを取得する
/// </summary>
/// <param name="folder">ファイルを検索するフォルダ名。</param>
/// <param name="searchPattern">ファイル名検索文字列
/// ワイルドカード指定子(*, ?)を使用する。</param>
/// <param name="files">見つかったファイル名のリスト</param>
public static void GetAllFiles(
    string folder, string searchPattern, ref ArrayList files)
{
    //folderにあるファイルを取得する
    string[] fs =
        System.IO.Directory.GetFiles(folder, searchPattern);
    //ArrayListに追加する
    files.AddRange(fs);

    //folderのサブフォルダを取得する
    string[] ds = System.IO.Directory.GetDirectories(folder);
    //サブフォルダにあるファイルも調べる
    foreach (string d in ds)
        GetAllFiles(d, searchPattern, ref files);
}

次にGetAllFilesメソッドの使い方を示します。ここではフォルダ"C:\test"以下にあるすべてのファイルのフルパスをリストボックス(ListBox1)に表示しています。

VB.NET
コードを隠すコードを選択
Dim files As New ArrayList
'"C:\test"以下のファイルをすべて取得
GetAllFiles("C:\test", "*.*", files)
'ListBox1に結果を表示する
ListBox1.Items.AddRange(files.ToArray())
C#
コードを隠すコードを選択
ArrayList files = new ArrayList();
//"C:\test"以下のファイルをすべて取得
GetAllFiles(@"C:\test", "*.*", ref files);
//ListBox1に結果を表示する
ListBox1.Items.AddRange(files.ToArray());
  • 履歴:
  • 2007/2/19 .NET Framework 2.0に関する記述を追加。
  • 2015/12/8 DirectoryInfo.GetFilesメソッドや、Directory.EnumerateFilesメソッドなどの説明を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。
共有する

この記事への評価
良い / 悪い = 142 / 11

この記事へのコメント
通常のコメント [ 匿名 ] 2022年6月13日 00:50:53
このGetFiles()、取得されるファイルパスの並び順序が全く頓着されません。
そうかといって、List<string>を定義しその中に取得したファイルパスを放り込み、Sort()をかけると、当然というか単純に昇降順にする為今度はディレクトリ階層構造を無視したソートがかかります。

なかなかのクズっぷりです(草

で、きちんとソートをかけてサブディレクトリまで含めた全ファイルを列挙しようと欲するならば、1階層づつ分離し都度そのサブディレクトリ内のファイルを取得し、ソート、といったコードを、結局自力実装するしかないようです orz

いや、記録メディア上の記録方法が分かっていればこうなるのは確かに理解できるのですが、普段GUI上でソート済みのフォルダウィンドウを見慣れていてこの動作を期待しちゃってる身としては、なんだコレは?! こんなもの使いモノになるか!! と思ってしまいませんかねぇw

参考までに。

評価の理由 [ x86 ] 2021年12月8日 09:22:29
評価:良い
参考になりました!

通常のコメント [ e ] 2021年11月3日 11:15:22
C#フォームアプリ.NETframework4.6.1のプロジェクト内で、リムーバブルドライブ内のファイルを検索すると「System.IO.Directory.EnumerateFiles」でも「GetFiles」でも結果が
F:\folder\......
とならず
F:folder\......
となり最初の「\」がとれてしまいます。

コンソールアプリで実行すると上記のような問題は起きません。
原因がわからず困っています。

通常のコメント [ 直之介 ] 2020年7月17日 03:36:17
Directory.EnumerateFiles でファイル名の取得を行った後に、MessageBoxOptions.DefaultDesktopOnlyオプションをつけたメッセージボックスが表示されなくなるので注意が必要です。
これの解決で、1日潰してしまいました(ToT)。

System.Windows.Forms.MessageBox.Show("Test", "Test", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1, System.Windows.Forms.MessageBoxOptions.DefaultDesktopOnly);
//IEnumerable<string> files = Directory.EnumerateFiles(strTmp, "*.csv");
string[] files = Directory.GetFiles(strTmp, "*.csv"); //これならOK

System.Windows.Forms.MessageBox.Show("Test2", "Test", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1, System.Windows.Forms.MessageBoxOptions.DefaultDesktopOnly); //Directory.EnumerateFilesを使用すると表示されない

評価の理由 [ 匿名 ] 2020年5月15日 00:20:40
評価:良い
参考になりました。
いつも助かっています。


この記事に関するコメントを投稿するには、下のボタンをクリックしてください。投稿フォームへ移動します。通常のご質問、ご意見等は掲示板へご投稿ください。
Google 翻訳

原文

翻訳を改善する