Path.Combine() / Path.GetFileName()
| 対応: | C# 1.0(2002) |
|---|
ファイルパスを安全に結合する『Path.Combine()』と、パスからファイル名部分を取り出す『Path.GetFileName()』などの使い方です。
構文
// パスを結合します(OS のパス区切り文字を自動補完します) Path.Combine(string path1, string path2) Path.Combine(params string[] paths) // パスからファイル名(拡張子含む)を取得します Path.GetFileName(string path) // パスから拡張子なしのファイル名を取得します Path.GetFileNameWithoutExtension(string path) // パスから拡張子を取得します(先頭にドットが付きます) Path.GetExtension(string path) // パスからディレクトリ部分を取得します Path.GetDirectoryName(string path)
メソッド一覧
| メソッド | 概要 |
|---|---|
| Path.Combine(path1, path2) | 2つ以上のパスを結合します。OS の区切り文字(Windows は \、Linux/Mac は /)を自動で挿入します。 |
| Path.GetFileName(path) | パス文字列からファイル名(拡張子含む)だけを返します。 |
| Path.GetFileNameWithoutExtension(path) | 拡張子を除いたファイル名を返します。 |
| Path.GetExtension(path) | 拡張子を返します(例:.txt)。拡張子がない場合は空文字列を返します。 |
| Path.GetDirectoryName(path) | ファイル名を除いたディレクトリ部分を返します。 |
| Path.GetFullPath(path) | 相対パスを絶対パスに変換します。 |
| Path.GetTempPath() | システムの一時ファイルディレクトリのパスを返します。 |
サンプルコード
Program.cs
using System; using System.IO; // Path.Combine() でパスを結合します string folder = @"C:\Users\eva_user\documents"; string fileName = "report.txt"; string fullPath = Path.Combine(folder, fileName); Console.WriteLine(fullPath); // C:\Users\eva_user\documents\report.txt // 3つ以上のパスも結合できます string savePath = Path.Combine(@"C:\data", "2024", "01", "log.csv"); Console.WriteLine(savePath); // C:\data\2024\01\log.csv // Path.GetFileName() でファイル名を取り出します string path = @"C:\Users\eva_user\documents\report.txt"; Console.WriteLine(Path.GetFileName(path)); // report.txt Console.WriteLine(Path.GetFileNameWithoutExtension(path)); // report Console.WriteLine(Path.GetExtension(path)); // .txt Console.WriteLine(Path.GetDirectoryName(path)); // C:\Users\eva_user\documents // 一時ファイルの保存先を取得します string tempDir = Path.GetTempPath(); Console.WriteLine(tempDir); // 例: C:\Users\eva_user\AppData\Local\Temp\
dotnet script path_combine_getfilename.csx C:\Users\eva_user\documents\report.txt C:\data\2024\01\log.csv report.txt report .txt C:\Users\eva_user\documents C:\Users\eva_user\AppData\Local\Temp\
上記は Windows 環境での実行結果です。macOS/Linux では区切り文字がスラッシュ(/)になります。
実践パターン: 日付付きログファイル名の生成
実行日時からログファイルのパスを生成するパターンです。複数回呼んでも一貫したパスが得られます。
LogPathBuilder.cs
using System;
using System.IO;
string logDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"EvaApp",
"logs"
);
// 日付付きのログファイル名を生成します
string logFileName = $"app_{DateTime.Today:yyyyMMdd}.log";
string logFilePath = Path.Combine(logDir, logFileName);
Console.WriteLine($"ログディレクトリ: {logDir}");
Console.WriteLine($"ログファイル: {logFilePath}");
// ディレクトリを作成してからファイルを保存します
Directory.CreateDirectory(logDir);
File.AppendAllText(logFilePath, $"[{DateTime.Now:HH:mm:ss}] 起動\n");
// ファイル情報を分解して確認します
Console.WriteLine($"ファイル名: {Path.GetFileName(logFilePath)}");
Console.WriteLine($"拡張子: {Path.GetExtension(logFilePath)}");
Console.WriteLine($"ディレクトリ: {Path.GetDirectoryName(logFilePath)}");
// 後片付けします
Directory.Delete(logDir, recursive: true);
dotnet script log_path_builder.csx ログディレクトリ: /Users/eva_user/Library/Application Support/EvaApp/logs ログファイル: /Users/eva_user/Library/Application Support/EvaApp/logs/app_20240115.log ファイル名: app_20240115.log 拡張子: .log ディレクトリ: /Users/eva_user/Library/Application Support/EvaApp/logs
実践パターン: ファイルの拡張子でフィルタリング
ディレクトリ内のファイル一覧から特定の拡張子のファイルだけを処理するパターンです。
ExtensionFilter.cs
using System;
using System.IO;
using System.Linq;
// テスト用ファイルを準備します
string testDir = "test_assets";
Directory.CreateDirectory(testDir);
File.WriteAllText(Path.Combine(testDir, "shinji.png"), "png");
File.WriteAllText(Path.Combine(testDir, "rei.jpg"), "jpg");
File.WriteAllText(Path.Combine(testDir, "asuka.png"), "png");
File.WriteAllText(Path.Combine(testDir, "kaworu.txt"), "txt");
File.WriteAllText(Path.Combine(testDir, "misato.json"), "json");
// 全ファイルを取得して拡張子を確認します
string[] allFiles = Directory.GetFiles(testDir);
Console.WriteLine("--- 全ファイル ---");
foreach (string f in allFiles)
{
string name = Path.GetFileName(f);
string ext = Path.GetExtension(f);
Console.WriteLine($" {name} (拡張子: {ext})");
}
// 画像ファイル(.png, .jpg)だけを抽出します
var imageFiles = allFiles
.Where(f => Path.GetExtension(f).ToLower() is ".png" or ".jpg")
.Select(f => Path.GetFileName(f))
.ToList();
Console.WriteLine($"--- 画像ファイル ({imageFiles.Count}件) ---");
foreach (string img in imageFiles)
Console.WriteLine($" {img}");
// 後片付けします
Directory.Delete(testDir, recursive: true);
dotnet script extension_filter.csx --- 全ファイル --- asuka.png (拡張子: .png) kaworu.txt (拡張子: .txt) misato.json (拡張子: .json) rei.jpg (拡張子: .jpg) shinji.png (拡張子: .png) --- 画像ファイル (3件) --- asuka.png rei.jpg shinji.png
よくあるミス
よくあるミス1: パスを文字列連結で組み立てる
文字列連結でパスを組み立てると、OS によって異なるパス区切り文字や、スラッシュの重複・欠落が起きます。
path_bad.cs
using System; using System.IO; // NG: 区切り文字を手書きすると OS 依存・スラッシュ重複などの問題が起きます string bad = "work" + "/" + "logs" + "/" + "app.log"; // Windows では \ が期待されますが / が入ります // NG: 末尾にスラッシュがある場合の二重スラッシュ string dir = "work/logs/"; string badPath = dir + "app.log"; // work/logs//app.log になります
path_good.cs
using System;
using System.IO;
// OK: Path.Combine() は区切り文字を自動補完します
string good = Path.Combine("work", "logs", "app.log");
Console.WriteLine(good); // Windows: work\logs\app.log macOS: work/logs/app.log
// OK: 末尾スラッシュがあっても自動で補正されます
string goodPath = Path.Combine("work/logs/", "app.log");
Console.WriteLine(goodPath); // work/logs/app.log(重複しません)
dotnet run work/logs/app.log work/logs/app.log
よくあるミス2: GetDirectoryName が null を返す場合
ルートディレクトリのパスや、ディレクトリ部分のないファイル名だけを渡すと GetDirectoryName は null を返します。
using System;
using System.IO;
// NG: null になるケースを考慮しないと NullReferenceException が発生します
string rootPath = @"C:\";
string? dir1 = Path.GetDirectoryName(rootPath); // null を返します
Console.WriteLine(dir1 ?? "null"); // null
string fileName = "report.txt"; // ディレクトリ部分なし
string? dir2 = Path.GetDirectoryName(fileName); // "" (空文字列) を返します
Console.WriteLine($"空: '{dir2}'");
dotnet run null 空: ''
修正後は次の通りです。
using System;
using System.IO;
// OK: null チェックを挟みます
string? safeDir = Path.GetDirectoryName(@"C:\Users\eva_user\report.txt");
if (safeDir != null)
Console.WriteLine($"ディレクトリ: {safeDir}");
dotnet run ディレクトリ: C:\Users\eva_user
概要
『Path.Combine()』は文字列を直接連結するよりも安全なパスの結合方法です。区切り文字の重複や欠落を自動的に補正するため、Windows・Linux・Mac のいずれの環境でも同じコードが動作します。
パスを手動で文字列連結(path1 + "\\" + path2)するとOS による動作の違いや区切り文字ミスが起きやすいため、必ず『Path.Combine()』を使います。
ファイルの読み書きには『File.ReadAllText() / File.WriteAllText()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。