ファイルをリネームする際、特に「拡張子だけを変えたい(例:.jpeg → .jpg)」という場合、手動で文字列操作を行うとドットの位置の判定などでミスが起きがちです。
Path.ChangeExtension メソッドを使用すると、パス文字列内の拡張子部分だけを安全に書き換えた新しいパス文字列を取得できます。 ※重要: このメソッドは「新しいパスの文字列」を作るだけで、実際のファイル名は変わりません。ファイル名を変更するには、その後に File.Move を呼ぶ必要があります。
目次
実装サンプル:誤った拡張子の修正
以下のコードでは、拡張子が誤って .text となってしまったファイルを、正しい .txt に変更する処理を行っています。
サンプルコード
using System;
using System.IO;
public class Program
{
public static void Main()
{
// 1. 準備:テスト用のファイルを作成(拡張子が .text)
string originalPath = "memo.text";
if (!File.Exists(originalPath))
{
File.WriteAllText(originalPath, "これはテストです。");
}
Console.WriteLine($"変更前: {originalPath}");
// 2. 新しい拡張子を持つパス文字列を作成
// 第1引数: 元のパス
// 第2引数: 新しい拡張子(ドットを含めても省略してもOK)
// ※この時点ではまだファイル名は変わっていません!
string newPath = Path.ChangeExtension(originalPath, ".txt");
Console.WriteLine($"変更後(予定): {newPath}");
// 3. 実際にファイル名を変更する (移動処理)
if (File.Exists(originalPath))
{
// 移動先に同名ファイルがないか確認してから実行するのが安全
if (!File.Exists(newPath))
{
File.Move(originalPath, newPath);
Console.WriteLine("ファイル名の変更が完了しました。");
}
else
{
Console.WriteLine("エラー: 変更後のファイル名が既に存在します。");
}
}
}
}
実行結果
変更前: memo.text
変更後(予定): memo.txt
ファイル名の変更が完了しました。
解説と技術的なポイント
1. Path.ChangeExtension の挙動
このメソッドは、ファイルシステムにはアクセスせず、純粋に文字列の置換を行います。
- 文字列の末尾にある拡張子を探し、指定された拡張子に置き換えます。
- 第2引数に
nullを渡すと、拡張子を除去したパス(memo)を返します。 - 第2引数のドットは省略可能です(
"txt"と書いても自動的に.txtになります)。
2. File.Move との組み合わせ
初心者が陥りやすいミスとして、「Path.ChangeExtension を呼んだだけでファイルが変わる」と勘違いするケースがあります。 必ず File.Move(旧パス, 新パス) を実行して、OSに対してリネーム操作を指示する必要があります。
3. 一時ファイルの利用
拡張子を変えるだけでなく、一時的な作業ファイル(.tmp)を作成し、処理が完了したら正式な拡張子(.csvなど)に変更するといったトランザクション的な処理にもこの手法はよく利用されます。
