DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ファイル名に使用できない文字列が含まれていないか調べる

ここでは、指定した文字列に、ファイル名やフォルダ名(以下、ファイル名)に使用できない文字や文字列が含まれていないか調べる方法を紹介します。

しかしここで紹介している方法は完全な方法ではありませんので、本当にそのファイル名でファイルを作成できるかは、実際にファイルを作成してみることでしか確認できないでしょう。

なお、ファイル名に使用できない文字が含まれている場合これをすべて削除する方法は、「文字列から指定した文字を削除する」を参考にしてください。

Path.GetInvalidFileNameCharsメソッドを使用する方法

ファイル名に使用できない文字は、Path.GetInvalidFileNameCharsメソッドで取得できます。また、ファイルのパスに使用できない文字は、Path.GetInvalidPathCharsメソッドで取得できます。

これらのメソッドは.NET Framework 2.0以降でしか使用できませんので、それ未満であれば、代わりにPath.InvalidPathCharsフィールド(Path.GetInvalidPathCharsメソッドと同等)を使います。

具体的には、GetInvalidPathChars内の文字は、1〜31のASCII/Unicode文字、引用符(")、不等号(<と>)、パイプ(|)、null(\0)の36文字になります。GetInvalidFileNameCharsはこれに加えて、コロン(:)、アスタリスク(*)、クエスチョンマーク(?)、スラッシュ(/)、バックスラッシュ(\)の41文字になります。

ただし、ヘルプには、「ファイル名やディレクトリ名としては無効なすべての文字が含まれるかどうかは、保証されません。」と無責任なことが書かれていますので、これだけを信用することはできません。

以下にGetInvalidFileNameCharsメソッドを使ってファイル名に使用できない文字が含まれていないか調べる例を示します。.NET Framework 2.0以降で実行可能です。

VB.NET
コードを隠すコードを選択
'調べるファイル名
Dim fileName As String = "abc.txt"

'ファイル名に使用できない文字を取得
Dim invalidChars As Char() = System.IO.Path.GetInvalidFileNameChars()

If fileName.IndexOfAny(invalidChars) < 0 Then
    Console.WriteLine("ファイル名に使用できない文字は使われていません。")
Else
    Console.WriteLine("ファイル名に使用できない文字が使われています。")
End If
C#
コードを隠すコードを選択
//調べるファイル名
string fileName = "abc.txt";

//ファイル名に使用できない文字を取得
char[] invalidChars = System.IO.Path.GetInvalidFileNameChars();

if (fileName.IndexOfAny(invalidChars) < 0)
{
    Console.WriteLine("ファイル名に使用できない文字は使われていません。");
}
else
{
    Console.WriteLine("ファイル名に使用できない文字が使われています。");
}

正規表現を使用する方法

Naming Files, Paths, and Namespaces」によると、ファイル名に使用できない名前は、先に紹介した文字を含んだ名前の他に、以下のようなものがあります。

  • 以下の予約された名前。これらの名前のすぐ後に拡張子があるファイル名もダメ(例えば、「con.txt」)。
    CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
  • 末尾にスペースやピリオドのある名前。

これに加えて、「CLOCK$」、「COM0」、「LPT0」も使用できないという話もあります。(私がWindows 8.1で試した限りでは、「CLOCK$」はエクスプローラで作成できました。また、拡張子があれば、「CLOCK$」を使用できるという話もあります。)

以上の情報を基に、不正なファイル名を正規表現で調べるサンプルを作ってみました。

VB.NET
コードを隠すコードを選択
'確認したいファイル名
Dim f As String = "test.txt"
'不正なファイル名をチェックする正規表現
Dim r As New System.Text.RegularExpressions.Regex( _
    "[\x00-\x1f<>:""/\\|?*]" & _
    "|^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9]|CLOCK\$)(\.|$)" & _
    "|[\. ]$", _
    System.Text.RegularExpressions.RegexOptions.IgnoreCase)
'マッチしたら、不正なファイル名
If r.IsMatch(f) Then
    Console.WriteLine("不正なファイル名です。")
End If
C#
コードを隠すコードを選択
//確認したいファイル名
string f = "test.txt";
//不正なファイル名をチェックする正規表現
System.Text.RegularExpressions.Regex r =
    new System.Text.RegularExpressions.Regex(
        "[\\x00-\\x1f<>:\"/\\\\|?*]" +
        "|^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9]|CLOCK\\$)(\\.|$)" + 
        "|[\\. ]$",
    System.Text.RegularExpressions.RegexOptions.IgnoreCase);
//マッチしたら、不正なファイル名
if (r.IsMatch(f))
{
    Console.WriteLine("不正なファイル名です。");
}

Path.GetFullPathなどのメソッドが例外をスローするか調べる方法

Path.GetFullPathメソッドは、指定されたパスが正しいかをある程度調べ、不正と判断した場合は、例外をスローします。例えば、パスに使用できない文字が含まれている場合はArgumentException、アクセス許可がない場合はSecurityException、ボリューム識別子(「C:\」など)以外に「:」がある場合はNotSupportedException、パスの長さが長すぎる(フルパスの長さが260文字以上)場合はPathTooLongExceptionがスローされます。

Path.GetFullPathメソッド以外にも、FileInfoコンストラクタなどを使っても、ほぼ同じことができます。

この方法は例外を発生させることで調べるため、あまり良い方法とは言えないでしょう。

以下に、この方法を使ってファイル名が正しいか調べるメソッドの例を示します。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 指定されたファイル名に不正がないかチェックする
''' </summary>
''' <param name="fileName">チェックするファイル名。</param>
''' <returns>不正がないと判断された場合は、True。それ以外は、False。</returns>
Public Shared Function IsValidFileName(fileName As String) As Boolean
    Try
        'GetFullPathメソッドに渡して、例外がスローされるか確かめる
        System.IO.Path.GetFullPath(fileName)
    Catch ex As ArgumentException
        'ファイル名に不正な文字が含まれている場合など
        Return False
    Catch ex As System.Security.SecurityException
        'アクセスできない場合
        Return False
    Catch ex As NotSupportedException
        'ボリューム識別子以外に「:」がある場合
        Return False
    Catch ex As System.IO.PathTooLongException
        'パス名が長すぎる場合
        Return False
    End Try

    Return True
End Function
C#
コードを隠すコードを選択
/// <summary>
/// 指定されたファイル名に不正がないかチェックする
/// </summary>
/// <param name="fileName">チェックするファイル名。</param>
/// <returns>不正がないと判断された場合は、True。それ以外は、False。</returns>
public static bool IsValidFileName(string fileName)
{
    try
    {
        //GetFullPathメソッドに渡して、例外がスローされるか確かめる
        System.IO.Path.GetFullPath(fileName);
    }
    catch (ArgumentException)
    {
        //ファイル名に不正な文字が含まれている場合など
        return false;
    }
    catch (System.Security.SecurityException)
    {
        //アクセスできない場合
        return false;
    }
    catch (NotSupportedException)
    {
        //ボリューム識別子以外に「:」がある場合
        return false;
    }
    catch (System.IO.PathTooLongException)
    {
        //パス名が長すぎる場合
        return false;
    }

    return true;
}
  • 履歴:
  • 2009/10/28 GetInvalidPathCharsとGetInvalidFileNameCharsが返す具体的な文字の説明を追加。
  • 2013/9/1 「文字列から指定した文字を削除する」へのリンク切れを修正。
  • 2016/5/14 「正規表現を使用する方法」と「Path.GetFullPathなどのメソッドが例外をスローするか調べる方法」を追加。

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

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