特定の文字列がWindowsで有効なファイル名であるかどうかを確認するにはどうすればよいですか?


165

アプリケーションにバッチファイルの名前変更機能を含めたいのですが。ユーザーは宛先ファイル名のパターンを入力できます(パターン内のいくつかのワイルドカードを置き換えた後)、それがWindowsで有効なファイル名になるかどうかを確認する必要があります。のように正規表現を使用しようとしました[a-zA-Z0-9_]+が、さまざまな言語(ウムラウトなど)からの国固有の文字が多く含まれていません。そのようなチェックを行う最良の方法は何ですか?


私は..あなたが正規表現と回答のいずれかを使用しようとしている場合、正規表現コンパイル静的を使用することをお勧め
AMissico

回答:


100

Path.GetInvalidPathCharsおよびから無効な文字のリストを取得できますGetInvalidFileNameChars

UPD:正規表現でこれらを使用する方法に関するSteve Cooperの提案を参照してください。

UPD2: MSDNの備考セクションによると、「このメソッドから返される配列には、ファイル名とディレクトリ名で無効な文字の完全なセットが含まれているとは限りません。」sixlettervaliablesによって提供される答えは、より詳細になります。


11
これは質問には答えません。有効なファイル名ではない有効な文字のみで構成される多くの文字列(「....」、「CON」、数百文字の文字列など)があります。
Dour High Arch 2013

31
MSがこの機能のためのシステムレベルの機能/ APIを提供しておらず、各開発者が自分のソリューションを作成する必要がないことに失望した人はいますか?これには非常に正当な理由があるのか​​、それともMSの部分を見落としているのか疑問に思います。
Thomas Nguyen 14年

@High Arch:「C#で、ファイル名がおそらく有効であること(存在しないこと)を確認してください。(一部の賢い人がこの質問を支持してその質問を閉じましたが...)
mmmmmmmm

129

MSDNの「ファイルまたはディレクトリの命名」から Windowsでの正当なファイル名の一般的な規則は次のとおりです。

現在のコードページ(127を超えるUnicode / ANSI)では、次の文字を除く任意の文字を使用できます。

  • < > : " / \ | ? *
  • 整数表現が0〜31の文字(ASCIIスペース未満)
  • ターゲットファイルシステムで許可されていないその他の文字(たとえば、末尾のピリオドまたはスペース)
  • 任意のDOS名:CON、PRN、AUX、NUL、COM0、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT0、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、 LPT8、LPT9(およびAUX.txtなどは避けてください)
  • ファイル名はすべてピリオドです

チェックするオプションの事項:

  • ファイルパス(ファイル名を含む)は260文字以下にする必要があります(\?\プレフィックスを使用しません)
  • 使用時に32,000文字を超えるUnicodeファイルパス(ファイル名を含む)\?\(接頭辞がディレクトリコンポーネントを展開し、32,000の制限をオーバーフローさせる可能性があることに注意してください)

8
予約されたファイル名を含めるための+1-以前の回答では見逃されていました。
SqlRyan 2009

2
「\\?\」構文を使用する場合、「AUX」は完全に使用可能なファイル名です。もちろん、その構文を使用しないプログラムには、その処理に実際の問題があります...(XPでテスト済み)
user9876

9
上記すべてのこれらの条件の正しい正規表現は以下の通りである:Regex unspupportedRegex = new Regex("(^(PRN|AUX|NUL|CON|COM[1-9]|LPT[1-9]|(\\.+)$)(\\..*)?$)|(([\\x00-\\x1f\\\\?*:\";|/<>])+)|(([\\. ]+)", RegexOptions.IgnoreCase);
whywhywhy

4
@whywhywhyそのRegexに余分な開始ブラケットがあると思います。"(^(PRN | AUX | NUL | CON | COM [1-9] | LPT [1-9] |(\\。+)$)(\\ .. *)?$)|(([\\ x00-\\ x1f \\\\?*:\ "; ‌ | / <>])+)|([\\。] +)"がうまく
いき

4
この回答で述べた同じ記事を読んだところ、実験によりCOM0とLPT0も許可されていないことがわかりました。@dlfこれは、「。」で始まるファイル名で機能します:^(?!^(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)(?:\.*?(?!\.))[^\x00-\x1f\\?*:\";|\/<>]+(?<![\s.])$
mjohnsonengr

67

3.5より前の.Net Frameworksの場合、これは機能するはずです。

正規表現のマッチングにより、何らかの方法が得られるはずです。これはSystem.IO.Path.InvalidPathChars定数を使用したスニペットです。

bool IsValidFilename(string testName)
{
    Regex containsABadCharacter = new Regex("[" 
          + Regex.Escape(System.IO.Path.InvalidPathChars) + "]");
    if (containsABadCharacter.IsMatch(testName)) { return false; };

    // other checks for UNC, drive-path format, etc

    return true;
}

以下のための.Netフレームワーク3.0の後にこの作業をする必要があります:

http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars(v=vs.90).aspx

正規表現のマッチングにより、何らかの方法が得られるはずです。これはSystem.IO.Path.GetInvalidPathChars()定数を使用したスニペットです。

bool IsValidFilename(string testName)
{
    Regex containsABadCharacter = new Regex("["
          + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]");
    if (containsABadCharacter.IsMatch(testName)) { return false; };

    // other checks for UNC, drive-path format, etc

    return true;
}

あなたがそれを知ったら、あなたはまた、例えば、異なるフォーマットをチェックする必要がありますc:\my\driveし、\\server\share\dir\file.ext


これはファイル名ではなくパスのみをテストしませんか?
Eugene Katz

30
string strTheseAreInvalidFileNameChars = new string(System.IO.Path.GetInvalidFileNameChars()); Regex regFixFileName = new Regex( "[" + Regex.Escape(strTheseAreInvalidFileNameChars)+ "]");
rao

2
人からの少しの研究は不思議に働くでしょう。変更を反映するように投稿を更新しました。
Erik Philips、

1
2番目のコードがコンパイルされません。「char []から文字列に変換できない
Paul Hunt

1
@AshkanMobayenKhiabani:InvalidPathCharsは廃止されましたが、GetInvalidPathCharsは廃止されていません。
IvanH

25

それを使用してみて、エラーをトラップしてください。許可されたセットは、ファイルシステム間で、またはWindowsの異なるバージョン間で変更される可能性があります。つまり、Windowsがその名前を気に入っているかどうかを知りたい場合は、その名前を渡して教えてもらいます。


1
これは、すべての制約に対してテストする唯一のもののようです。なぜこれに対して他の答えが選ばれるのですか?
ギャップ

5
@gapは常に機能するとは限らないためです。たとえば、実際のファイルではない場合でも、CONにアクセスしようとすると成功することがよくあります。
アンチモン2010年

4
ただし、可能であれば、例外をスローすることによるメモリオーバーヘッドを回避することをお勧めします。
オーウェンブラッカー

2
また、それにアクセスする権限がない場合もあります。たとえば、存在するか存在するかどうかを読み取ることができる場合でも、書き込みによってテストします。
CodeLurker 2017

23

このクラスは、ファイル名とパスをクリーンアップします。好きに使う

var myCleanPath = PathSanitizer.SanitizeFilename(myBadPath, ' ');

これがコードです。

/// <summary>
/// Cleans paths of invalid characters.
/// </summary>
public static class PathSanitizer
{
    /// <summary>
    /// The set of invalid filename characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidFilenameChars;
    /// <summary>
    /// The set of invalid path characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidPathChars;

    static PathSanitizer()
    {
        // set up the two arrays -- sorted once for speed.
        invalidFilenameChars = System.IO.Path.GetInvalidFileNameChars();
        invalidPathChars = System.IO.Path.GetInvalidPathChars();
        Array.Sort(invalidFilenameChars);
        Array.Sort(invalidPathChars);

    }

    /// <summary>
    /// Cleans a filename of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizeFilename(string input, char errorChar)
    {
        return Sanitize(input, invalidFilenameChars, errorChar);
    }

    /// <summary>
    /// Cleans a path of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizePath(string input, char errorChar)
    {
        return Sanitize(input, invalidPathChars, errorChar);
    }

    /// <summary>
    /// Cleans a string of invalid characters.
    /// </summary>
    /// <param name="input"></param>
    /// <param name="invalidChars"></param>
    /// <param name="errorChar"></param>
    /// <returns></returns>
    private static string Sanitize(string input, char[] invalidChars, char errorChar)
    {
        // null always sanitizes to null
        if (input == null) { return null; }
        StringBuilder result = new StringBuilder();
        foreach (var characterToTest in input)
        {
            // we binary search for the character in the invalid set. This should be lightning fast.
            if (Array.BinarySearch(invalidChars, characterToTest) >= 0)
            {
                // we found the character in the array of 
                result.Append(errorChar);
            }
            else
            {
                // the character was not found in invalid, so it is valid.
                result.Append(characterToTest);
            }
        }

        // we're done.
        return result.ToString();
    }

}

1
あなたの答えは、より良いここにフィットすることができますstackoverflow.com/questions/146134/...
nawfal

22

これは私が使用するものです:

    public static bool IsValidFileName(this string expression, bool platformIndependent)
    {
        string sPattern = @"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\"";|/]+$";
        if (platformIndependent)
        {
           sPattern = @"^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?))\\)*[^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?$";
        }
        return (Regex.IsMatch(expression, sPattern, RegexOptions.CultureInvariant));
    }

最初のパターンは、Windowsプラットフォームの場合のみ、無効/不正なファイル名と文字を含む正規表現を作成します。2番目のものも同じことを行いますが、名前がどのプラットフォームでも合法であることを確認します。


4
sPattern正規表現では、ピリオド文字で始まるファイルは許可されません。しかし、MSDNは「名前の最初の文字としてピリオドを指定することは許容されます。たとえば、「。temp」」と言います。「\ .. *」を削除して、.gitignoreに正しいファイル名を作成します:)
yar_shukan '10

(私はこれを徐々に改善し、私が残した前のコメントを削除しました)これは「.gitignore」、「.. asdf」を許可し、「<」と「>」または円を許可しないため、回答の正規表現よりも優れています記号、および末尾にスペースまたはピリオドを許可しない(ドットのみで構成される名前は許可されません):@"^(?!(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)[^\x00-\x1F\xA5\\?*:\"";|\/<>]+(?<![\s.])$"
mjohnsonengr '14

これは、私がテストしたすべてのファイルで失敗します。C:\ Windows \ System32 \ msxml6.dllに対して実行すると、falseが報告されます。
magicandre1981 2016年

@ magicandre1981完全修飾パスではなく、ファイル名のみを指定する必要があります。
スコットドーマン2016年

わかりましたが、フルパスが有効かどうかを確認する必要があります。今は別のソリューションを使用しました。
magicandre1981

18

Windowsでファイル名の先頭にスペース文字を使用できるようになりました。たとえば、以下はすべてWindowsでの合法で明確なファイル名です(引用符を除く)。

"file.txt"
" file.txt"
"  file.txt"

これからの1つの要点:ファイル名の文字列から先頭/末尾の空白を削除するコードを書くときは注意してください。


10

ユージーン・カッツの答えを単純化する:

bool IsFileNameCorrect(string fileName){
    return !fileName.Any(f=>Path.GetInvalidFileNameChars().Contains(f))
}

または

bool IsFileNameCorrect(string fileName){
    return fileName.All(f=>!Path.GetInvalidFileNameChars().Contains(f))
}

もしかして: "return!fileName.Any(f => Path.GetInvalidFileNameChars()。Contains(f));" ?
ジャックグリフィン

@JackGriffinもちろん!ご清聴ありがとうございました。
2018年

このコードは非常に読みやすいものですが、の申し訳ありませんが内部を考慮に入れる必要がありPath.GetInvalidFileNameCharsます。こちらをご覧ください:referencesource.microsoft.com/#mscorlib/system/io/path.cs,289-の各文字fileNameについて、配列のクローンが作成されます。
Piotr Zierhoffer

「DD:\\\\\ AAA ..... AAAA」。有効ではありませんが、コードでは有効です。
Ciccio Pasticcio

8

Microsoft Windows:Windowsカーネルでは、1〜31の範囲の文字(つまり0x01-0x1F)と文字 "*:<>?\ |を使用できません。NTFSでは、各パスコンポーネント(ディレクトリまたはファイル名)の長さを255文字にすることができます。パスは最大32767文字まで、Windowsカーネルは最大259文字までのパスのみをサポートします。さらに、WindowsはMS-DOSデバイス名AUX、CLOCK $、COM1、COM2、COM3、COM4、COM5、COM6、 COM7、COM8、COM9、CON、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8、LPT9、NUL、PRN、およびこれらの名前に拡張子(たとえば、AUX.txt)を付けたもの(使用する場合を除く)長いUNCパス(例:\。\ C:\ nul.txtまたは\?\ D:\ aux \ con)(実際、CLOCK $は拡張機能が提供されている場合に使用できます。)これらの制限はWindowsにのみ適用されます-たとえば、Linuxでは "*:<>?\ | NTFSでもです。

出典:http : //en.wikipedia.org/wiki/Filename


1
「CLOCK $」という名前のファイルを作成できます。Windows 7.
rory.ap 2017

7

考えられるすべての文字を明示的に含めるのではなく、正規表現を使用して不正な文字の存在を確認し、エラーを報告することができます。理想的には、アプリケーションはユーザーの希望どおりにファイルに名前を付け、エラーに遭遇した場合にのみ反則する必要があります。


6

問題は、パス名が有効なWindowsパスであるかどうか、またはコードが実行されているシステムで有効かどうかを判断しようとしていることです?後者の方が重要だと思うので、個人的にはおそらくフルパスを分解し、_mkdirを使用してファイルが属するディレクトリを作成してから、ファイルを作成してみます。

これにより、パスに有効なWindows文字のみが含まれるかどうかだけでなく、実際にこのプロセスで書き込めるパスを表すかどうかもわかります。


6

これを使用して、例外をスローせずにファイル名の無効な文字を削除します。

private static readonly Regex InvalidFileRegex = new Regex(
    string.Format("[{0}]", Regex.Escape(@"<>:""/\|?*")));

public static string SanitizeFileName(string fileName)
{
    return InvalidFileRegex.Replace(fileName, string.Empty);
}

5

また、CON、PRN、AUX、NUL、COM#およびその他のいくつかは、任意の拡張子を持つディレクトリ内の正当なファイル名にはなりません。


1
これは真実の半分にすぎません。ユニコードバージョンのCreateFile(ファイル名の前に「\\?\」を付ける)を呼び出すと、これらの名前でファイルを作成できます。
Werner Henze 2013

このステートメントは不完全で、LPT番号がありません
Thomas Weller

4

他の回答を補足するために、考慮すべき追加のエッジケースをいくつか示します。

  • 名前に「[」または「]」の文字が含まれるファイルにブックを保存すると、Excelで問題が発生する可能性があります。詳細については、http://support.microsoft.com/kb/215205を参照してください。

  • SharePointには、追加の一連の制限があります。詳細については、http://support.microsoft.com/kb/905231を参照してください。


3

MSDNから、許可されていない文字のリストを次に示します。

Unicode文字や拡張文字セット(128〜255)の文字を含む、現在のコードページのほとんどすべての文字を名前に使用します。ただし、次のものは除きます。

  • 次の予約文字は使用できません:<>: "/ \ |?*
  • 整数表現が0から31の範囲にある文字は許可されません。
  • ターゲットファイルシステムで許可されていないその他の文字。

2

また、宛先ファイルシステムも重要です。

NTFSでは、特定のディレクトリに作成できないファイルがあります。EG $ Boot in root


2
確かに、それはNTFSの命名規則によるものではなく、単に呼び出されたファイル$Bootがディレクトリに既に存在しているためです。
Christian Hayter、2010

2

これは既に回答済みの質問ですが、「その他のオプション」のために、理想的ではないものを次に示します。

(例外をフロー制御として使用することは一般的に「悪いこと」であるため、理想的ではありません)

public static bool IsLegalFilename(string name)
{
    try 
    {
        var fileInfo = new FileInfo(name);
        return true;
    }
    catch
    {
        return false;
    }
}

あなたの例は、CONファイル(C:\ temp \ CON)では機能しませんでした。
tcbrazil 2015年

しかし、「C:\ temp \ CON」は有効なファイル名ではありませんか?なんでだろう?
Mark A. Donohoe、2015年

@MarqueIV-いいえ、無効です。上記のすべての回答とコメントを読むか、自分で試して見てください。
rory.ap 2017

@Jer、「/ example」は不正ですが、メソッドはを返しますtrue
rory.ap 2017

ああ... CONの部分を逃してしまいました。名前自体は文字列の観点からは有効ですが(これは私が参照していたものです)、CONは予約済みの名前であるため、Windowsの観点からは無効です。私の悪い。
マークA.ドノホー2017

2

正規表現は、この状況ではやりすぎです。このString.IndexOfAny()メソッドは、Path.GetInvalidPathChars()およびと組み合わせて使用できますPath.GetInvalidFileNameChars()

また、どちらのPath.GetInvalidXXX()メソッドも内部配列を複製し、その複製を返すことにも注意してください。そのため、これを何度も(数千回、数千回)行う場合は、無効な文字配列のコピーをキャッシュして再利用できます。


2

ファイル名/パスを保持する文字列に無効な文字が含まれているかどうかを確認するだけの場合、私が見つけた最も速い方法はSplit()、無効な文字がある場所にファイル名をパーツの配列に分割することです。結果が1の配列のみの場合、無効な文字はありません。:-)

var nameToTest = "Best file name \"ever\".txt";
bool isInvalidName = nameToTest.Split(System.IO.Path.GetInvalidFileNameChars()).Length > 1;

var pathToTest = "C:\\My Folder <secrets>\\";
bool isInvalidPath = pathToTest.Split(System.IO.Path.GetInvalidPathChars()).Length > 1;

私は、LinqPadで1,000,000回、ファイル/パス名に対して上記の方法と他の方法を実行してみました。

使用Split()はわずか850msです。

使用Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]")は約6秒です。

より複雑な正規表現は、Pathクラスのさまざまなメソッドを使用してファイル名を取得し、それらの内部検証に仕事を任せるなど、他のオプションの一部と同様に、かなり公平に処理します(例外処理のオーバーヘッドが原因と考えられます)。

100万のファイル名を検証する必要があることはそれほど頻繁ではないので、いずれにしても、これらのメソッドのほとんどで1回の反復で問題ありません。しかし、無効な文字だけを探している場合でも、かなり効率的で効果的です。


1

ファイル名が長すぎてWindows 10より前の環境で実行されている場合、これらの回答の多くは機能しません。同様に、ピリオドで何をしたいかを考えてください。先行または後続の許可は技術的には有効ですが、ファイルの表示や削除をそれぞれ困難にしたくない場合は問題が発生する可能性があります。

これは、有効なファイル名を確認するために作成した検証属性です。

public class ValidFileNameAttribute : ValidationAttribute
{
    public ValidFileNameAttribute()
    {
        RequireExtension = true;
        ErrorMessage = "{0} is an Invalid Filename";
        MaxLength = 255; //superseeded in modern windows environments
    }
    public override bool IsValid(object value)
    {
        //http://stackoverflow.com/questions/422090/in-c-sharp-check-that-filename-is-possibly-valid-not-that-it-exists
        var fileName = (string)value;
        if (string.IsNullOrEmpty(fileName)) { return true;  }
        if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) > -1 ||
            (!AllowHidden && fileName[0] == '.') ||
            fileName[fileName.Length - 1]== '.' ||
            fileName.Length > MaxLength)
        {
            return false;
        }
        string extension = Path.GetExtension(fileName);
        return (!RequireExtension || extension != string.Empty)
            && (ExtensionList==null || ExtensionList.Contains(extension));
    }
    private const string _sepChar = ",";
    private IEnumerable<string> ExtensionList { get; set; }
    public bool AllowHidden { get; set; }
    public bool RequireExtension { get; set; }
    public int MaxLength { get; set; }
    public string AllowedExtensions {
        get { return string.Join(_sepChar, ExtensionList); } 
        set {
            if (string.IsNullOrEmpty(value))
            { ExtensionList = null; }
            else {
                ExtensionList = value.Split(new char[] { _sepChar[0] })
                    .Select(s => s[0] == '.' ? s : ('.' + s))
                    .ToList();
            }
    } }

    public override bool RequiresValidationContext => false;
}

そしてテスト

[TestMethod]
public void TestFilenameAttribute()
{
    var rxa = new ValidFileNameAttribute();
    Assert.IsFalse(rxa.IsValid("pptx."));
    Assert.IsFalse(rxa.IsValid("pp.tx."));
    Assert.IsFalse(rxa.IsValid("."));
    Assert.IsFalse(rxa.IsValid(".pp.tx"));
    Assert.IsFalse(rxa.IsValid(".pptx"));
    Assert.IsFalse(rxa.IsValid("pptx"));
    Assert.IsFalse(rxa.IsValid("a/abc.pptx"));
    Assert.IsFalse(rxa.IsValid("a\\abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c:abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c<abc.pptx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
    rxa = new ValidFileNameAttribute { AllowedExtensions = ".pptx" };
    Assert.IsFalse(rxa.IsValid("abc.docx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
}

1

私の試み:

using System.IO;

static class PathUtils
{
  public static string IsValidFullPath([NotNull] string fullPath)
  {
    if (string.IsNullOrWhiteSpace(fullPath))
      return "Path is null, empty or white space.";

    bool pathContainsInvalidChars = fullPath.IndexOfAny(Path.GetInvalidPathChars()) != -1;
    if (pathContainsInvalidChars)
      return "Path contains invalid characters.";

    string fileName = Path.GetFileName(fullPath);
    if (fileName == "")
      return "Path must contain a file name.";

    bool fileNameContainsInvalidChars = fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1;
    if (fileNameContainsInvalidChars)
      return "File name contains invalid characters.";

    if (!Path.IsPathRooted(fullPath))
      return "The path must be absolute.";

    return "";
  }
}

Path.GetInvalidPathChars、ファイル名やディレクトリ名で無効な文字の完全なセットを返さないため、完璧ではありません。もちろん、さらに多くの微妙な点があります。

だから私はこの方法を補足として使用します:

public static bool TestIfFileCanBeCreated([NotNull] string fullPath)
{
  if (string.IsNullOrWhiteSpace(fullPath))
    throw new ArgumentException("Value cannot be null or whitespace.", "fullPath");

  string directoryName = Path.GetDirectoryName(fullPath);
  if (directoryName != null) Directory.CreateDirectory(directoryName);
  try
  {
    using (new FileStream(fullPath, FileMode.CreateNew)) { }
    File.Delete(fullPath);
    return true;
  }
  catch (IOException)
  {
    return false;
  }
}

例外がある場合は、ファイルを作成してfalseを返します。もちろん、ファイルを作成する必要がありますが、それが最も安全な方法だと思います。また、作成されたディレクトリは削除しないことに注意してください。

最初の方法を使用して基本的な検証を行い、パスが使用されている場合は例外を注意深く処理することもできます。


0

Path.GetFullPath()を使用することをお勧めします

string tagetFileFullNameToBeChecked;
try
{
  Path.GetFullPath(tagetFileFullNameToBeChecked)
}
catch(AugumentException ex)
{
  // invalid chars found
}

現在の問題を修正する方法で、この答えのヘルプOPのための答えを持ついくつかの説明を追加
ρяσѕρєяK

AugumentExcpetionについては、MSDNのドキュメントを参照してください。パスは長さがゼロの文字列であるか、空白のみが含まれているか、GetInvalidPathCharsで定義されている1つ以上の無効な文字が含まれています。-または-システムが絶対パスを取得できませんでした。
トニー・サン

理論的には(ドキュメントによると)これは機能するはずですが、少なくとも.NET Core 3.1では問題がありますが、機能しません。
ミシェルヤンソン

0

私は誰かからこのアイデアを得ました。-誰だかわからない。OSに大仕事を任せましょう。

public bool IsPathFileNameGood(string fname)
{
    bool rc = Constants.Fail;
    try
    {
        this._stream = new StreamWriter(fname, true);
        rc = Constants.Pass;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Problem opening file");
        rc = Constants.Fail;
    }
    return rc;
}

0

このチェック

static bool IsValidFileName(string name)
{
    return
        !string.IsNullOrWhiteSpace(name) &&
        name.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
        !Path.GetFullPath(name).StartsWith(@"\\.\");
}

無効な文字(と名前出フィルタ<>:"/\|?*およびASCII 0〜31)と同様に、予約済みのDOSデバイス(CONNULCOMx)。と一致して、先行スペースとすべてドット名を許​​可しPath.GetFullPathます。(先頭のスペースを含むファイルの作成は、私のシステムでは成功しています)。


Windows 7でテストされた.NET Framework 4.7.1を使用。


0

文字列内の不正な文字を検証するための1つのライナー:

public static bool IsValidFilename(string testName) => !Regex.IsMatch(testName, "[" + Regex.Escape(new string(System.IO.Path.InvalidPathChars)) + "]");

0

私の意見では、この質問に対する唯一の適切な答えは、パスを使用して、OSとファイルシステムに検証させることです。それ以外の場合は、OSとファイルシステムがすでに使用しているすべての検証ルールを再実装しているだけで(おそらく不十分です)、それらのルールが将来変更される場合は、それらに一致するようにコードを変更する必要があります。


-1

Windowsのファイル名はそう実際にそれがさえないかもしれない、かなり制限のないされているという問題の多く。Windowsで許可されていない文字は次のとおりです。

\ / : * ? " < > |

これらの文字が存在するかどうかを確認する式を簡単に作成できます。しかし、より良い解決策は、ユーザーが望むようにファイルに名前を付けて、ファイル名が付かないときに警告することです。


また、31以下の文字は禁止されています。
アンチモン2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.