C# Directory.GetFilesの使い方完全ガイド|フォルダ内のファイル取得・拡張子指定・サブフォルダ検索まで解説

はじめに

C#でフォルダ内のファイル一覧を取得したいとき、最もよく使われるメソッドのひとつがDirectory.GetFilesです。

たとえば、次のような処理を実装したい場面で役立ちます。

  • 指定フォルダ内のファイルを一覧表示する

  • .txt.csvなど特定の拡張子だけ取得する

  • サブフォルダ内のファイルまでまとめて検索する

  • 最新のファイルだけ取得する

  • 条件に合うファイルを読み込み、コピー、削除する

Directory.GetFilesはシンプルに使える一方で、戻り値、検索パターン、サブフォルダ検索、例外処理、パフォーマンス面の注意点を理解しておかないと、思わぬエラーや処理遅延につながることがあります。

この記事では、c# directory getfilesで知りたい基本から実践的な使い方まで、サンプルコード付きでわかりやすく解説します。

1. Directory.GetFilesとは?C#でフォルダ内のファイル一覧を取得する基本

Directory.GetFilesは、指定したディレクトリ内にあるファイルのパス一覧を取得するためのメソッドです。

C#では、ファイルやフォルダを操作するときにSystem.IO名前空間をよく使います。Directory.GetFilesもその中に含まれる代表的なメソッドです。

1-1. Directory.GetFilesでできること

Directory.GetFilesを使うと、主に次のような処理ができます。

指定したフォルダ内のすべてのファイルを取得できます。

C#
string[] files = Directory.GetFiles(@"C:\Work");

特定の拡張子だけを取得できます。

C#
string[] textFiles = Directory.GetFiles(@"C:\Work", "*.txt");

サブフォルダ内のファイルまで検索できます。

C#
string[] allFiles = Directory.GetFiles(
@"C:\Work",
"*.*",
SearchOption.AllDirectories
);

このように、Directory.GetFilesは「どのフォルダから」「どの条件で」「どの範囲まで」ファイルを探すかを指定できるメソッドです。

1-2. 戻り値はstring[]|取得できるのはファイルのフルパス

Directory.GetFilesの戻り値はstring[]です。

取得される文字列は、ファイル名だけではなく、パスを含むファイル名です。Microsoftの公式ドキュメントでも、指定ディレクトリ内のファイル名をパス付きで返し、該当ファイルがなければ空配列を返すと説明されています。

たとえば、次のような結果になります。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string file in files)
{
Console.WriteLine(file);
}

出力例は次のとおりです。

C:\Work\sample.txt
C:\Work\data.csv
C:\Work\image.png

ファイル名だけが必要な場合は、Path.GetFileNameを使います。

C#
foreach (string file in files)
{
Console.WriteLine(Path.GetFileName(file));
}

1-3. DirectoryクラスとSystem.IO名前空間の役割

Directory.GetFilesを使うには、通常はファイル先頭に次のusingを記述します。

C#
using System.IO;

System.IO名前空間には、ファイル、ディレクトリ、パス、ストリームなどを扱うためのクラスが用意されています。

代表的なクラスは次のとおりです。

クラス主な役割
Directoryフォルダの作成、削除、検索など
Fileファイルの作成、読み書き、コピー、削除など
Pathファイル名、拡張子、フォルダパスの分解・結合など
DirectoryInfoオブジェクト指向でフォルダ情報を扱う
FileInfoオブジェクト指向でファイル情報を扱う

Directory.GetFilesは静的メソッドなので、new Directory()のようにインスタンスを作成する必要はありません。

C#
string[] files = Directory.GetFiles(@"C:\Work");

1-4. Directory.GetFilesが向いている処理・向いていない処理

Directory.GetFilesが向いているのは、比較的小規模から中規模のフォルダで、取得したファイル一覧を配列としてまとめて扱いたい場合です。

たとえば、次のような処理に向いています。

  • フォルダ内のファイル一覧を画面に表示する

  • 指定拡張子のファイルを一括処理する

  • 取得結果をLINQで並び替える

  • 最新ファイルを1件だけ選ぶ

  • バッチ処理でファイルをコピーする

一方で、大量のファイルを扱う場合には注意が必要です。Directory.GetFilesは、条件に合うファイルをすべて取得してから配列として返します。Microsoftの公式ドキュメントでも、大量のファイルやディレクトリを扱う場合は、全件取得を待たずに列挙を開始できるDirectory.EnumerateFilesの方が効率的な場合があると説明されています。

2. Directory.GetFilesの基本的な使い方

ここからは、Directory.GetFilesの基本的なコードを見ていきましょう。

2-1. 指定フォルダ内の全ファイルを取得するコード例

指定フォルダ内のファイルをすべて取得する基本形は次のとおりです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = @"C:\Work";

string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
}

Directory.GetFiles(folderPath)と書くと、指定したフォルダ直下のファイル一覧を取得できます。

この書き方では、サブフォルダ内のファイルは取得されません。あくまで指定フォルダ直下のファイルだけが対象です。

2-2. foreachで取得したファイルパスを1件ずつ処理する

Directory.GetFilesの戻り値は配列なので、foreachで1件ずつ処理できます。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string filePath in files)
{
Console.WriteLine(filePath);
}

ファイルを読み込む場合は、次のように書けます。

C#
string[] files = Directory.GetFiles(@"C:\Work", "*.txt");

foreach (string filePath in files)
{
string content = File.ReadAllText(filePath);
Console.WriteLine(content);
}

ファイルをコピーする場合は、次のようになります。

C#
string sourceFolder = @"C:\Work";
string destFolder = @"C:\Backup";

string[] files = Directory.GetFiles(sourceFolder);

foreach (string filePath in files)
{
string fileName = Path.GetFileName(filePath);
string destPath = Path.Combine(destFolder, fileName);

File.Copy(filePath, destPath, overwrite: true);
}

2-3. 相対パスと絶対パスの指定方法

Directory.GetFilesには、絶対パスと相対パスのどちらも指定できます。公式ドキュメントでも、pathには相対パスまたは絶対パスを指定でき、相対パスは現在の作業ディレクトリを基準に解釈されると説明されています。

絶対パスの例です。

C#
string[] files = Directory.GetFiles(@"C:\Work");

相対パスの例です。

C#
string[] files = Directory.GetFiles(@"data");

この場合、アプリケーションの現在の作業ディレクトリの下にあるdataフォルダが対象になります。

現在の作業ディレクトリを確認したい場合は、次のようにします。

C#
Console.WriteLine(Directory.GetCurrentDirectory());

相対パスは環境によって基準位置が変わることがあるため、確実に指定したい場合は絶対パスを使うか、Path.Combineで安全にパスを組み立てるのがおすすめです。

C#
string basePath = AppContext.BaseDirectory;
string folderPath = Path.Combine(basePath, "data");

string[] files = Directory.GetFiles(folderPath);

2-4. ファイルが存在しない場合は空配列が返る

指定したフォルダが存在し、条件に一致するファイルがない場合、Directory.GetFilesnullではなく空配列を返します。公式ドキュメントにも、該当するファイルが見つからない場合は空配列を返すと記載されています。

C#
string[] files = Directory.GetFiles(@"C:\Work", "*.notfound");

Console.WriteLine(files.Length);

出力例です。

0

そのため、ファイルがあるかどうかを判定したい場合は、Lengthを確認します。

C#
if (files.Length == 0)
{
Console.WriteLine("ファイルが見つかりませんでした。");
}
else
{
Console.WriteLine($"{files.Length}件のファイルが見つかりました。");
}

ただし、指定したフォルダ自体が存在しない場合は空配列ではなく例外が発生します。この点は重要です。

3. 拡張子を指定してファイルを取得する方法

Directory.GetFilesでは、第2引数に検索パターンを指定することで、特定のファイルだけを取得できます。

C#
Directory.GetFiles(フォルダパス, 検索パターン)

検索パターンには、*.txt*.csvのようなワイルドカードを指定します。

3-1. 「*.txt」でテキストファイルだけ取得する

テキストファイルだけを取得するには、次のように書きます。

C#
string[] textFiles = Directory.GetFiles(@"C:\Work", "*.txt");

foreach (string file in textFiles)
{
Console.WriteLine(file);
}

*.txtは、「任意のファイル名で、拡張子が.txtのファイル」を意味します。

たとえば、次のようなファイルが取得対象になります。

memo.txt
readme.txt
log.txt

一方、次のファイルは対象外です。

memo.csv
readme.md
log.json

3-2. 「.csv」「.jpg」「*.xlsx」など拡張子別の指定例

拡張子別に取得する場合は、基本的に*.拡張子の形式で指定します。

CSVファイルを取得する例です。

C#
string[] csvFiles = Directory.GetFiles(@"C:\Work", "*.csv");

JPEG画像を取得する例です。

C#
string[] jpgFiles = Directory.GetFiles(@"C:\Images", "*.jpg");

Excelファイルを取得する例です。

C#
string[] excelFiles = Directory.GetFiles(@"C:\Reports", "*.xlsx");

PDFファイルを取得する例です。

C#
string[] pdfFiles = Directory.GetFiles(@"C:\Documents", "*.pdf");

拡張子を指定するときは、".csv"ではなく"*.csv"と書くのが基本です。

C#
// 正しい例
Directory.GetFiles(@"C:\Work", "*.csv");

// 意図した結果になりにくい例
Directory.GetFiles(@"C:\Work", ".csv");

3-3. 複数の拡張子を取得したい場合の書き方

Directory.GetFilessearchPatternには、*.jpg;*.pngのような複数パターンを直接まとめて指定することはできません。

複数の拡張子を取得したい場合は、拡張子ごとに取得して結合する方法がよく使われます。

C#
using System;
using System.IO;
using System.Linq;

string folderPath = @"C:\Images";

string[] imageFiles = Directory.GetFiles(folderPath, "*.jpg")
.Concat(Directory.GetFiles(folderPath, "*.png"))
.Concat(Directory.GetFiles(folderPath, "*.gif"))
.ToArray();

foreach (string file in imageFiles)
{
Console.WriteLine(file);
}

拡張子の一覧を配列で持たせると、より柔軟に書けます。

C#
using System;
using System.IO;
using System.Linq;

string folderPath = @"C:\Images";
string[] extensions = { ".jpg", ".png", ".gif" };

string[] imageFiles = Directory.GetFiles(folderPath)
.Where(file => extensions.Contains(Path.GetExtension(file).ToLower()))
.ToArray();

foreach (string file in imageFiles)
{
Console.WriteLine(file);
}

大文字・小文字を区別せずに比較したい場合は、次のように書くと安全です。

C#
string[] extensions = { ".jpg", ".png", ".gif" };

string[] imageFiles = Directory.GetFiles(folderPath)
.Where(file => extensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase))
.ToArray();

3-4. searchPatternで使えるワイルドカードの基本

Directory.GetFilesの第2引数searchPatternでは、ワイルドカードを使えます。公式ドキュメントでは、searchPatternに使用できるワイルドカードとして、*?が説明されています。また、正規表現はサポートされません。

よく使うパターンは次のとおりです。

searchPattern意味
"*.*"すべてのファイル
"*.txt"拡張子が.txtのファイル
"data*.csv"dataで始まるCSVファイル
"*2024*.log"ファイル名に2024を含むログファイル
"?.txt"1文字のファイル名を持つ.txtファイル
"file?.txt"file1.txtなど、fileの後に1文字続くファイル

使用例です。

C#
string[] files = Directory.GetFiles(@"C:\Work", "data*.csv");

この場合、次のようなファイルが対象になります。

data.csv
data_001.csv
data_backup.csv

3-5. 大文字・小文字の違いに注意すべきケース

Windows環境では、多くの場合、ファイル名の大文字・小文字は区別されません。そのため、*.jpgPHOTO.JPGが取得されることがあります。

一方、Linuxなどの環境では、ファイルシステムによって大文字・小文字が区別される場合があります。公式ドキュメントでも、パスの大文字・小文字の扱いは実行環境のファイルシステムに依存すると説明されています。

クロスプラットフォームで動かすアプリケーションでは、拡張子比較にStringComparer.OrdinalIgnoreCaseを使うと意図が明確になります。

C#
string[] extensions = { ".jpg", ".jpeg", ".png" };

string[] files = Directory.GetFiles(@"C:\Images")
.Where(file => extensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase))
.ToArray();

4. サブフォルダ内のファイルまで検索する方法

Directory.GetFilesは、既定では指定フォルダ直下のファイルだけを取得します。

サブフォルダ内のファイルまで取得したい場合は、第3引数にSearchOption.AllDirectoriesを指定します。

4-1. SearchOption.TopDirectoryOnlyとAllDirectoriesの違い

SearchOptionには主に次の2種類があります。

説明
SearchOption.TopDirectoryOnly指定フォルダ直下のみ検索
SearchOption.AllDirectoriesサブフォルダを含めて検索

Microsoftの公式ドキュメントでも、TopDirectoryOnlyは現在のディレクトリのみ、AllDirectoriesは現在のディレクトリとすべてのサブディレクトリを検索対象にすると説明されています。

既定の動作はTopDirectoryOnlyです。

C#
string[] files = Directory.GetFiles(
@"C:\Work",
"*.*",
SearchOption.TopDirectoryOnly
);

これは次の書き方とほぼ同じ意味です。

C#
string[] files = Directory.GetFiles(@"C:\Work");

4-2. サブディレクトリを含めて全ファイルを取得するコード例

サブフォルダ内のファイルまでまとめて取得するには、次のように書きます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = @"C:\Work";

string[] files = Directory.GetFiles(
folderPath,
"*.*",
SearchOption.AllDirectories
);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
}

たとえば、次のような構成があるとします。

C:\Work
├─ a.txt
├─ b.csv
└─ Sub
├─ c.txt
└─ d.csv

SearchOption.AllDirectoriesを指定すると、Subフォルダ内のc.txtd.csvも取得対象になります。

4-3. 特定拡張子をサブフォルダまで再帰的に検索する

.txtファイルだけをサブフォルダまで検索したい場合は、次のように書きます。

C#
string[] textFiles = Directory.GetFiles(
@"C:\Work",
"*.txt",
SearchOption.AllDirectories
);

foreach (string file in textFiles)
{
Console.WriteLine(file);
}

画像ファイルをサブフォルダまで検索したい場合は、次のようにLINQと組み合わせると便利です。

C#
using System;
using System.IO;
using System.Linq;

string folderPath = @"C:\Images";
string[] extensions = { ".jpg", ".jpeg", ".png", ".gif" };

string[] imageFiles = Directory.GetFiles(
folderPath,
"*.*",
SearchOption.AllDirectories)
.Where(file => extensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase))
.ToArray();

foreach (string file in imageFiles)
{
Console.WriteLine(file);
}

4-4. 深い階層を検索する場合のパフォーマンス注意点

SearchOption.AllDirectoriesは便利ですが、深い階層や大量のファイルを持つフォルダに対して使うと、処理に時間がかかることがあります。

特に次のようなケースでは注意が必要です。

  • ファイル数が数万件以上ある

  • サブフォルダが非常に多い

  • ネットワークドライブを検索する

  • 共有フォルダを検索する

  • UIアプリでメインスレッド上から実行する

Directory.GetFilesは、該当するファイルをすべて取得してから配列を返します。そのため、取得件数が多い場合はメモリ使用量が増えます。

大量ファイルを扱う場合は、Directory.EnumerateFilesを検討しましょう。

C#
foreach (string file in Directory.EnumerateFiles(
@"C:\Work",
"*.*",
SearchOption.AllDirectories))
{
Console.WriteLine(file);
}

EnumerateFilesは列挙しながら処理できるため、全件を配列に格納するGetFilesより効率的な場合があります。

4-5. アクセス権限がないフォルダで例外が発生するケース

SearchOption.AllDirectoriesを使うと、サブフォルダを再帰的に検索します。その途中にアクセス権限のないフォルダがあると、UnauthorizedAccessExceptionが発生することがあります。

C#
try
{
string[] files = Directory.GetFiles(
@"C:\",
"*.*",
SearchOption.AllDirectories
);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("アクセス権限がありません。");
Console.WriteLine(ex.Message);
}

特にC:\直下やシステムフォルダ、他ユーザーのフォルダを検索する場合は注意が必要です。

.NETではEnumerationOptionsを使うことで、アクセスできないフォルダを無視する設定もできます。

C#
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

string[] files = Directory.GetFiles(@"C:\Work", "*.*", options);

foreach (string file in files)
{
Console.WriteLine(file);
}

IgnoreInaccessible = trueを使うと、アクセスできない項目を無視して検索を継続しやすくなります。

5. Directory.GetFilesでよく使う実践パターン

ここでは、実務でよく使うDirectory.GetFilesの応用パターンを紹介します。

5-1. ファイル名だけを取得する

Directory.GetFilesで取得できるのはパス付きの文字列です。

ファイル名だけを取得したい場合は、Path.GetFileNameを使います。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string file in files)
{
string fileName = Path.GetFileName(file);
Console.WriteLine(fileName);
}

出力例です。

sample.txt
data.csv
image.png

拡張子なしのファイル名だけが欲しい場合は、Path.GetFileNameWithoutExtensionを使います。

C#
foreach (string file in files)
{
string name = Path.GetFileNameWithoutExtension(file);
Console.WriteLine(name);
}

5-2. ファイル名・拡張子・フォルダパスを分けて取得する

ファイルパスから、ファイル名、拡張子、フォルダパスを分けて取得するにはPathクラスを使います。

C#
string filePath = @"C:\Work\sample.txt";

string fileName = Path.GetFileName(filePath);
string nameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
string extension = Path.GetExtension(filePath);
string directoryName = Path.GetDirectoryName(filePath);

Console.WriteLine(fileName);
Console.WriteLine(nameWithoutExtension);
Console.WriteLine(extension);
Console.WriteLine(directoryName);

出力例です。

sample.txt
sample
.txt
C:\Work

Directory.GetFilesと組み合わせると、ファイル情報を一覧化できます。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string file in files)
{
Console.WriteLine($"ファイル名: {Path.GetFileName(file)}");
Console.WriteLine($"拡張子: {Path.GetExtension(file)}");
Console.WriteLine($"フォルダ: {Path.GetDirectoryName(file)}");
Console.WriteLine();
}

5-3. 更新日時が新しい順・古い順に並び替える

ファイルの更新日時で並び替えるには、File.GetLastWriteTimeとLINQを使います。

新しい順に並び替える例です。

C#
using System;
using System.IO;
using System.Linq;

string[] files = Directory.GetFiles(@"C:\Work")
.OrderByDescending(file => File.GetLastWriteTime(file))
.ToArray();

foreach (string file in files)
{
Console.WriteLine($"{File.GetLastWriteTime(file)} {Path.GetFileName(file)}");
}

古い順に並び替える例です。

C#
string[] files = Directory.GetFiles(@"C:\Work")
.OrderBy(file => File.GetLastWriteTime(file))
.ToArray();

Directory.GetFilesの取得順は保証されません。公式ドキュメントでも、返されるファイル名の順序は保証されないため、特定の順序が必要な場合は明示的に並び替える必要があると説明されています。

5-4. ファイルサイズで絞り込む

ファイルサイズで絞り込むには、FileInfoを使います。

1MB以上のファイルだけ取得する例です。

C#
using System;
using System.IO;
using System.Linq;

string[] largeFiles = Directory.GetFiles(@"C:\Work")
.Where(file => new FileInfo(file).Length >= 1024 * 1024)
.ToArray();

foreach (string file in largeFiles)
{
FileInfo info = new FileInfo(file);
Console.WriteLine($"{info.Name}: {info.Length} bytes");
}

10MB未満のファイルだけ取得する例です。

C#
string[] smallFiles = Directory.GetFiles(@"C:\Work")
.Where(file => new FileInfo(file).Length < 10 * 1024 * 1024)
.ToArray();

サイズ条件は、ログファイルの整理、容量の大きいファイルの抽出、バックアップ対象の選別などでよく使います。

5-5. LINQと組み合わせて条件検索する

Directory.GetFilesstring[]を返すため、LINQと相性が良いです。

たとえば、ファイル名にbackupを含むファイルだけ取得できます。

C#
string[] backupFiles = Directory.GetFiles(@"C:\Work")
.Where(file => Path.GetFileName(file).Contains("backup"))
.ToArray();

拡張子が.logで、更新日時が7日以内のファイルだけ取得する例です。

C#
string[] recentLogs = Directory.GetFiles(@"C:\Logs", "*.log")
.Where(file => File.GetLastWriteTime(file) >= DateTime.Now.AddDays(-7))
.ToArray();

ファイル名がdata_で始まるCSVだけ取得する例です。

C#
string[] dataFiles = Directory.GetFiles(@"C:\Work", "*.csv")
.Where(file => Path.GetFileName(file).StartsWith("data_"))
.ToArray();

5-6. 取得したファイルを読み込む・コピーする・削除する

取得したファイルを読み込む例です。

C#
string[] textFiles = Directory.GetFiles(@"C:\Work", "*.txt");

foreach (string file in textFiles)
{
string text = File.ReadAllText(file);
Console.WriteLine(text);
}

取得したファイルを別フォルダにコピーする例です。

C#
string sourceFolder = @"C:\Work";
string destFolder = @"C:\Backup";

Directory.CreateDirectory(destFolder);

foreach (string file in Directory.GetFiles(sourceFolder))
{
string destPath = Path.Combine(destFolder, Path.GetFileName(file));
File.Copy(file, destPath, overwrite: true);
}

取得した一時ファイルを削除する例です。

C#
string[] tempFiles = Directory.GetFiles(@"C:\Temp", "*.tmp");

foreach (string file in tempFiles)
{
File.Delete(file);
}

削除処理は取り消しが難しいため、事前に対象ファイルをログ出力する、確認画面を出す、バックアップを取るなどの対策を入れると安全です。

6. Directory.GetFilesで発生しやすいエラーと対処法

Directory.GetFilesはファイルシステムにアクセスするため、さまざまな例外が発生する可能性があります。代表的な例外として、DirectoryNotFoundExceptionUnauthorizedAccessExceptionArgumentExceptionArgumentNullExceptionPathTooLongExceptionIOExceptionなどがあります。

6-1. DirectoryNotFoundException|フォルダが存在しない

指定したフォルダが存在しない場合、DirectoryNotFoundExceptionが発生します。

C#
try
{
string[] files = Directory.GetFiles(@"C:\NotExists");
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine("フォルダが見つかりません。");
Console.WriteLine(ex.Message);
}

事前にDirectory.Existsで確認すると安全です。

C#
string folderPath = @"C:\NotExists";

if (Directory.Exists(folderPath))
{
string[] files = Directory.GetFiles(folderPath);
}
else
{
Console.WriteLine("指定されたフォルダは存在しません。");
}

6-2. UnauthorizedAccessException|アクセス権限がない

アクセス権限のないフォルダを検索すると、UnauthorizedAccessExceptionが発生することがあります。

C#
try
{
string[] files = Directory.GetFiles(@"C:\System Volume Information");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("アクセス権限がありません。");
Console.WriteLine(ex.Message);
}

対処法としては、次のような方法があります。

  • アクセス可能なフォルダだけを対象にする

  • 管理者権限が必要か確認する

  • try-catchで例外処理を入れる

  • EnumerationOptionsIgnoreInaccessibleを使う

C#
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

string[] files = Directory.GetFiles(@"C:\Work", "*.*", options);

6-3. ArgumentException・ArgumentNullException|パス指定が不正

pathnullの場合はArgumentNullExceptionが発生します。また、古い.NET環境では、空文字や不正な文字を含むパスでArgumentExceptionが発生することがあります。

C#
string folderPath = null;

try
{
string[] files = Directory.GetFiles(folderPath);
}
catch (ArgumentNullException ex)
{
Console.WriteLine("パスがnullです。");
Console.WriteLine(ex.Message);
}

ユーザー入力をパスとして使う場合は、空文字やnullをチェックしましょう。

C#
string folderPath = "";

if (string.IsNullOrWhiteSpace(folderPath))
{
Console.WriteLine("フォルダパスを入力してください。");
return;
}

string[] files = Directory.GetFiles(folderPath);

6-4. PathTooLongException|パスが長すぎる

パスやファイル名が長すぎる場合、PathTooLongExceptionが発生することがあります。

C#
try
{
string[] files = Directory.GetFiles(@"C:\Very\Long\Path\...");
}
catch (PathTooLongException ex)
{
Console.WriteLine("パスが長すぎます。");
Console.WriteLine(ex.Message);
}

深い階層のフォルダや、長いファイル名を扱うシステムでは注意が必要です。

対処法としては、次のような方法があります。

  • フォルダ階層を浅くする

  • ファイル名を短くする

  • 長いパスを扱う設定を確認する

  • 例外処理を入れてスキップできるようにする

6-5. IOException|ファイルやフォルダ操作中のエラー

IOExceptionは、入出力処理で発生する一般的な例外です。

Directory.GetFilesでは、指定したpathがファイル名だった場合や、ネットワークエラーが発生した場合などに発生する可能性があります。

C#
try
{
string[] files = Directory.GetFiles(@"C:\Work\sample.txt");
}
catch (IOException ex)
{
Console.WriteLine("入出力エラーが発生しました。");
Console.WriteLine(ex.Message);
}

ネットワークドライブや共有フォルダを扱う場合は、接続状態によってIOExceptionが発生することがあります。

6-6. 事前にDirectory.Existsで存在確認する方法

フォルダが存在するかどうかを事前に確認するには、Directory.Existsを使います。

C#
string folderPath = @"C:\Work";

if (!Directory.Exists(folderPath))
{
Console.WriteLine("フォルダが存在しません。");
return;
}

string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}

ただし、Directory.Existsで確認した直後にフォルダが削除される可能性もあります。そのため、存在確認だけでなく、最終的にはtry-catchも併用するのが安全です。

C#
try
{
if (!Directory.Exists(folderPath))
{
Console.WriteLine("フォルダが存在しません。");
return;
}

string[] files = Directory.GetFiles(folderPath);
}
catch (Exception ex)
{
Console.WriteLine("ファイル一覧の取得に失敗しました。");
Console.WriteLine(ex.Message);
}

7. Directory.GetFilesと関連メソッドの違い

C#には、Directory.GetFiles以外にもファイルやフォルダを取得するためのメソッドがあります。用途に応じて使い分けることが大切です。

7-1. Directory.GetFilesとDirectory.EnumerateFilesの違い

Directory.GetFilesは、条件に一致するファイルをすべて取得してからstring[]として返します。

一方、Directory.EnumerateFilesは、ファイルを列挙しながら処理できます。公式ドキュメントでも、EnumerateFilesはコレクション全体が返る前に列挙を開始でき、GetFilesは配列全体が返るまで待つ必要があると説明されています。

GetFilesの例です。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string file in files)
{
Console.WriteLine(file);
}

EnumerateFilesの例です。

C#
foreach (string file in Directory.EnumerateFiles(@"C:\Work"))
{
Console.WriteLine(file);
}

少量のファイルならどちらでも問題ありませんが、大量のファイルを扱う場合はEnumerateFilesが向いていることがあります。

7-2. 大量ファイルを扱うならEnumerateFilesを検討する

大量ファイルを扱うときにDirectory.GetFilesを使うと、すべてのパスを配列に格納するため、メモリ使用量が増えます。

たとえば、ログファイルを1件ずつ読み込んで処理するだけなら、EnumerateFilesの方が適しています。

C#
foreach (string file in Directory.EnumerateFiles(@"C:\Logs", "*.log"))
{
string text = File.ReadAllText(file);
Console.WriteLine(text.Length);
}

条件に一致した時点で処理を止めたい場合にも、EnumerateFilesは便利です。

C#
string latestFile = Directory.EnumerateFiles(@"C:\Logs", "*.log")
.OrderByDescending(file => File.GetLastWriteTime(file))
.FirstOrDefault();

Console.WriteLine(latestFile);

ただし、並び替えを行う場合は、結局すべての要素を評価する必要があります。処理内容に応じて選びましょう。

7-3. Directory.GetDirectoriesとの違い

Directory.GetFilesはファイルを取得します。

Directory.GetDirectoriesはフォルダを取得します。

C#
string[] files = Directory.GetFiles(@"C:\Work");
string[] directories = Directory.GetDirectories(@"C:\Work");

たとえば、次のような構成があるとします。

C:\Work
├─ sample.txt
├─ data.csv
└─ SubFolder

Directory.GetFiles(@"C:\Work")では、sample.txtdata.csvが取得されます。

Directory.GetDirectories(@"C:\Work")では、SubFolderが取得されます。

7-4. Directory.GetFileSystemEntriesとの違い

Directory.GetFileSystemEntriesは、ファイルとフォルダの両方を取得します。

C#
string[] entries = Directory.GetFileSystemEntries(@"C:\Work");

foreach (string entry in entries)
{
Console.WriteLine(entry);
}

ファイルだけ欲しい場合はGetFiles、フォルダだけ欲しい場合はGetDirectories、両方欲しい場合はGetFileSystemEntriesを使うとわかりやすいです。

7-5. DirectoryInfo.GetFilesとの使い分け

DirectoryInfo.GetFilesは、FileInfo[]を返します。

C#
DirectoryInfo dir = new DirectoryInfo(@"C:\Work");

FileInfo[] files = dir.GetFiles();

foreach (FileInfo file in files)
{
Console.WriteLine(file.Name);
Console.WriteLine(file.Length);
Console.WriteLine(file.LastWriteTime);
}

Directory.GetFilesstring[]を返すため、パス文字列だけ欲しい場合に便利です。

DirectoryInfo.GetFilesFileInfoオブジェクトを返すため、ファイルサイズ、更新日時、属性などを頻繁に使う場合に便利です。

使い分けの目安は次のとおりです。

メソッド戻り値向いている用途
Directory.GetFilesstring[]ファイルパス一覧が欲しい
Directory.EnumerateFilesIEnumerable<string>大量ファイルを順次処理したい
DirectoryInfo.GetFilesFileInfo[]ファイル情報をまとめて扱いたい

8. Directory.GetFilesを使うときの注意点・ベストプラクティス

Directory.GetFilesは便利ですが、実務で使う場合はいくつか注意点があります。

8-1. 大量ファイル取得時はメモリ使用量に注意する

Directory.GetFilesは、結果を配列として一度に返します。

そのため、対象ファイルが非常に多い場合は、メモリ使用量が増えます。

C#
string[] files = Directory.GetFiles(
@"C:\Logs",
"*.log",
SearchOption.AllDirectories
);

このコードはシンプルですが、ログファイルが大量にある環境では重くなる可能性があります。

大量ファイルを1件ずつ処理するだけなら、次のようにEnumerateFilesを使う方が向いています。

C#
foreach (string file in Directory.EnumerateFiles(
@"C:\Logs",
"*.log",
SearchOption.AllDirectories))
{
Console.WriteLine(file);
}

8-2. 例外処理を入れて安全にファイル検索する

ファイル検索では、フォルダが存在しない、権限がない、ネットワークエラーが発生するなど、さまざまな問題が起こります。

実務コードでは、try-catchを入れておくと安全です。

C#
try
{
string[] files = Directory.GetFiles(@"C:\Work", "*.txt");

foreach (string file in files)
{
Console.WriteLine(file);
}
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("フォルダが存在しません。");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("アクセス権限がありません。");
}
catch (IOException ex)
{
Console.WriteLine("入出力エラーが発生しました。");
Console.WriteLine(ex.Message);
}

すべての例外をcatch (Exception)でまとめて処理することもできますが、原因に応じたメッセージを出したい場合は、例外の種類ごとに分けるとよいです。

8-3. ユーザー入力のパスを扱うときの注意点

ユーザーが入力したパスをそのままDirectory.GetFilesに渡す場合は注意が必要です。

たとえば、次のような入力がありえます。

  • 空文字

  • 存在しないフォルダ

  • ファイルのパス

  • アクセスできないフォルダ

  • 想定外のネットワークパス

最低限、次のようなチェックを入れましょう。

C#
Console.Write("フォルダパスを入力してください: ");
string folderPath = Console.ReadLine();

if (string.IsNullOrWhiteSpace(folderPath))
{
Console.WriteLine("パスが入力されていません。");
return;
}

if (!Directory.Exists(folderPath))
{
Console.WriteLine("指定されたフォルダは存在しません。");
return;
}

try
{
string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
catch (Exception ex)
{
Console.WriteLine("ファイル一覧の取得に失敗しました。");
Console.WriteLine(ex.Message);
}

ユーザー入力を扱う場合は、エラーになる前提で安全に処理することが重要です。

8-4. ネットワークドライブや共有フォルダ検索時の注意点

ネットワークドライブや共有フォルダを検索する場合、ローカルフォルダよりもエラーが起きやすくなります。

注意したいポイントは次のとおりです。

  • ネットワーク接続が切れる可能性がある

  • アクセス権限がユーザーによって異なる

  • ファイル数が多いと処理が遅くなる

  • 共有フォルダの応答が遅い場合がある

  • 実行環境によってドライブレターが存在しない場合がある

たとえば、Z:\Sharedのようなネットワークドライブは、実行ユーザーによって見えないことがあります。

共有フォルダを扱う場合は、UNCパスを使うことも検討します。

C#
string folderPath = @"\\server\share";

string[] files = Directory.GetFiles(folderPath);

ネットワーク越しの検索では、例外処理とタイムアウト対策、検索範囲の限定が重要です。

8-5. UIアプリでは検索処理を非同期化する

Windows Forms、WPF、MAUIなどのUIアプリでDirectory.GetFilesを実行する場合、メインスレッドで重い検索処理を行うと画面が固まることがあります。

そのため、ファイル検索は非同期で実行するのがおすすめです。

C#
using System;
using System.IO;
using System.Threading.Tasks;

async Task SearchFilesAsync()
{
string folderPath = @"C:\Work";

string[] files = await Task.Run(() =>
Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories)
);

foreach (string file in files)
{
Console.WriteLine(file);
}
}

UIアプリでは、検索中にキャンセルできるようにする、進捗を表示する、検索範囲を限定するなどの工夫も有効です。

9. Directory.GetFilesの実用サンプルコード集

ここでは、すぐに使える実用サンプルをまとめます。

9-1. フォルダ内の全ファイルを一覧表示する

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = @"C:\Work";

if (!Directory.Exists(folderPath))
{
Console.WriteLine("フォルダが存在しません。");
return;
}

string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
}

指定フォルダ直下のファイルだけを一覧表示する基本サンプルです。

9-2. 指定拡張子のファイルだけを一覧表示する

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = @"C:\Work";
string extension = "*.csv";

string[] files = Directory.GetFiles(folderPath, extension);

foreach (string file in files)
{
Console.WriteLine(Path.GetFileName(file));
}
}
}

.csvファイルだけを取得し、ファイル名だけを表示しています。

9-3. サブフォルダを含めて画像ファイルを検索する

C#
using System;
using System.IO;
using System.Linq;

class Program
{
static void Main()
{
string folderPath = @"C:\Images";
string[] extensions = { ".jpg", ".jpeg", ".png", ".gif" };

string[] imageFiles = Directory.GetFiles(
folderPath,
"*.*",
SearchOption.AllDirectories)
.Where(file => extensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase))
.ToArray();

foreach (string file in imageFiles)
{
Console.WriteLine(file);
}
}
}

複数の画像拡張子を対象にし、サブフォルダまで再帰的に検索するサンプルです。

9-4. 最新ファイルを1件だけ取得する

C#
using System;
using System.IO;
using System.Linq;

class Program
{
static void Main()
{
string folderPath = @"C:\Logs";

string latestFile = Directory.GetFiles(folderPath, "*.log")
.OrderByDescending(file => File.GetLastWriteTime(file))
.FirstOrDefault();

if (latestFile == null)
{
Console.WriteLine("ログファイルが見つかりませんでした。");
return;
}

Console.WriteLine("最新ファイル:");
Console.WriteLine(latestFile);
}
}

更新日時が最も新しいファイルを1件だけ取得しています。

9-5. 複数条件でファイルを絞り込む

C#
using System;
using System.IO;
using System.Linq;

class Program
{
static void Main()
{
string folderPath = @"C:\Reports";

string[] files = Directory.GetFiles(folderPath, "*.xlsx")
.Where(file => Path.GetFileName(file).Contains("売上"))
.Where(file => File.GetLastWriteTime(file) >= DateTime.Now.AddMonths(-1))
.Where(file => new FileInfo(file).Length > 0)
.ToArray();

foreach (string file in files)
{
Console.WriteLine(file);
}
}
}

この例では、次の条件をすべて満たすファイルだけを取得しています。

  • 拡張子が.xlsx

  • ファイル名に売上を含む

  • 更新日時が1か月以内

  • ファイルサイズが0より大きい

9-6. 例外処理付きで安全にファイル一覧を取得する

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = @"C:\Work";

try
{
if (!Directory.Exists(folderPath))
{
Console.WriteLine("指定されたフォルダは存在しません。");
return;
}

string[] files = Directory.GetFiles(folderPath, "*.txt");

if (files.Length == 0)
{
Console.WriteLine("対象ファイルは見つかりませんでした。");
return;
}

foreach (string file in files)
{
Console.WriteLine(file);
}
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("アクセス権限がありません。");
Console.WriteLine(ex.Message);
}
catch (IOException ex)
{
Console.WriteLine("入出力エラーが発生しました。");
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("予期しないエラーが発生しました。");
Console.WriteLine(ex.Message);
}
}
}

実務では、このように存在確認と例外処理を組み合わせると安全です。

10. よくある質問

10-1. Directory.GetFilesでファイル名だけ取得できますか?

Directory.GetFiles自体が返すのは、パス付きのファイル名です。

ファイル名だけを取得したい場合は、Path.GetFileNameを使います。

C#
string[] files = Directory.GetFiles(@"C:\Work");

foreach (string file in files)
{
Console.WriteLine(Path.GetFileName(file));
}

拡張子なしの名前だけが欲しい場合は、Path.GetFileNameWithoutExtensionを使います。

C#
Console.WriteLine(Path.GetFileNameWithoutExtension(file));

10-2. 複数の拡張子を一度に指定できますか?

Directory.GetFilessearchPatternに、複数の拡張子をまとめて指定することはできません。

たとえば、次のような指定は期待どおりには動きません。

C#
Directory.GetFiles(@"C:\Work", "*.jpg;*.png");

複数拡張子を扱いたい場合は、LINQで絞り込む方法が便利です。

C#
string[] extensions = { ".jpg", ".png" };

string[] files = Directory.GetFiles(@"C:\Work")
.Where(file => extensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase))
.ToArray();

10-3. サブフォルダだけを除外できますか?

サブフォルダを検索対象にしたくない場合は、SearchOption.TopDirectoryOnlyを指定します。

C#
string[] files = Directory.GetFiles(
@"C:\Work",
"*.*",
SearchOption.TopDirectoryOnly
);

また、第3引数を省略した場合も、基本的には指定フォルダ直下だけが対象になります。

C#
string[] files = Directory.GetFiles(@"C:\Work");

10-4. 隠しファイルやシステムファイルも取得されますか?

Directory.GetFilesは、検索条件に一致するファイルを取得します。隠しファイルやシステムファイルを明示的に除外したい場合は、File.GetAttributesFileInfo.Attributesを使って絞り込みます。

C#
string[] files = Directory.GetFiles(@"C:\Work")
.Where(file =>
{
FileAttributes attr = File.GetAttributes(file);
return !attr.HasFlag(FileAttributes.Hidden)
&& !attr.HasFlag(FileAttributes.System);
})
.ToArray();

隠しファイルを除外したい、通常ファイルだけを表示したい、といった場合は属性チェックを追加しましょう。

10-5. Directory.GetFilesの取得順は決まっていますか?

取得順は保証されません。

公式ドキュメントでも、返されるファイル名の順序は保証されないため、特定の順序が必要な場合は明示的に並び替える必要があると説明されています。

ファイル名順にしたい場合は、次のようにします。

C#
string[] files = Directory.GetFiles(@"C:\Work")
.OrderBy(file => file)
.ToArray();

更新日時の新しい順にしたい場合は、次のようにします。

C#
string[] files = Directory.GetFiles(@"C:\Work")
.OrderByDescending(file => File.GetLastWriteTime(file))
.ToArray();

10-6. ファイルが多いと処理が遅い場合はどうすればいいですか?

ファイル数が多い場合は、次の対策を検討してください。

  • Directory.EnumerateFilesを使う

  • 検索対象フォルダを絞る

  • 拡張子などの条件を指定する

  • サブフォルダ検索を避ける

  • UIアプリでは非同期処理にする

  • ネットワークフォルダでは検索範囲を限定する

Directory.GetFilesは全件取得後に配列を返すため、大量ファイルでは重くなることがあります。

順次処理でよい場合は、次のようにDirectory.EnumerateFilesを使いましょう。

C#
foreach (string file in Directory.EnumerateFiles(@"C:\Logs", "*.log"))
{
Console.WriteLine(file);
}

全件を配列として保持する必要がないなら、EnumerateFilesの方が効率的な選択になることがあります。

まとめ

Directory.GetFilesは、C#でフォルダ内のファイル一覧を取得するための基本メソッドです。

指定フォルダ内の全ファイルを取得するだけなら、次のように簡単に書けます。

C#
string[] files = Directory.GetFiles(@"C:\Work");

拡張子を指定する場合は、*.txt*.csvのように検索パターンを指定します。

C#
string[] files = Directory.GetFiles(@"C:\Work", "*.txt");

サブフォルダまで検索する場合は、SearchOption.AllDirectoriesを指定します。

C#
string[] files = Directory.GetFiles(
@"C:\Work",
"*.*",
SearchOption.AllDirectories
);

実務で使う際は、次のポイントを押さえておきましょう。

  • 戻り値はstring[]

  • 取得できるのはパス付きのファイル名

  • ファイルが見つからない場合は空配列

  • フォルダが存在しない場合は例外

  • 取得順は保証されない

  • 複数拡張子はLINQで絞り込むと便利

  • 大量ファイルではDirectory.EnumerateFilesも検討する

  • アクセス権限やネットワークエラーに備えて例外処理を入れる

Directory.GetFilesを正しく使えるようになると、ファイル一覧表示、ログ処理、データ取込、画像検索、バックアップ処理など、さまざまなC#アプリケーションで応用できます。