/ / .Net:パス内の不正な文字を確認するにはどうすればよいですか? -.net、パス、違法文字

.Net:パス内の違法文字をチェックするにはどうしたらいいですか? - .net、パス、不正な文字

文字列がを意味するかどうかを確認する方法はありますか.Netでパスに無効な文字が含まれていますか? Path.InvalidPathCharsの各文字を反復処理して、文字列に文字列が含まれているかどうかを確認できることはわかっていますが、単純な、おそらくより形式的なソリューションを好みます。

あるの?

Getに対してのみチェックすると例外が発生することがわかりました

更新:

GetInvalidPathCharsがカバーしていないことがわかりましたすべての無効なパス文字。 GetInvalidFileNameCharsには、「?」を含む5つがあります。これに切り替えます。これに切り替えて、それでも不十分であることがわかった場合は報告します。

アップデート2:

GetInvalidFileNameCharsは間違いなく私のものではありません欲しいです。絶対パスに含まれる「:」が含まれます(「C:whatever」)。結局のところ、GetInvalidPathCharsを使用し、「?」などの文字を追加する必要があると思います。問題が発生したときに、それらを追加する必要があります。

回答:

回答№1の場合は36

InvalidPathCharsは非推奨です。代わりにGetInvalidPathChars()を使用してください。

    public static bool FilePathHasInvalidChars(string path)
{

return (!string.IsNullOrEmpty(path) && path.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0);
}

編集:少し長くなりますが、1つの関数でパスとファイルの無効な文字を処理します。

    // WARNING: Not tested
public static bool FilePathHasInvalidChars(string path)
{
bool ret = false;
if(!string.IsNullOrEmpty(path))
{
try
{
// Careful!
//    Path.GetDirectoryName("C:DirectorySubDirectory")
//    returns "C:Directory", which may not be what you want in
//    this case. You may need to explicitly add a trailing 
//    if path is a directory and not a file path. As written,
//    this function just assumes path is a file path.
string fileName = System.IO.Path.GetFileName(path);
string fileDirectory = System.IO.Path.GetDirectoryName(path);

// we don"t need to do anything else,
// if we got here without throwing an
// exception, then the path does not
// contain invalid characters
}
catch (ArgumentException)
{
// Path functions will throw this
// if path contains invalid chars
ret = true;
}
}
return ret;
}

回答№2については4

頼るときは注意してください Path.GetInvalidFileNameChars、これはあなたが思うほど信頼できないかもしれません。」 Path.GetInvalidFileNameChars

このメソッドから返される配列は ファイル名とディレクトリ名に無効な文字の完全なセットが含まれているとは限りません。 無効な文字の完全なセットは、ファイルシステム。たとえば、Windowsベースのデスクトッププラットフォームでは、無効なパス文字にはASCII / Unicode文字1〜31、引用符( ")、より小さい(<)、より大きい(>)、パイプ(|)、バックスペース( b)、null(

それは、「 Path.GetInvalidPathChars 方法。まったく同じ発言が含まれています。


答え№3の2

おそらくあなたには遅すぎますが、他の誰かを助けるかもしれません。 私は同じ問題に直面し、パスを消毒するための信頼できる方法を見つける必要がありました。

ここに私が3つのステップで使用したものがあります:

ステップ1:カスタムクリーニング。

public static string RemoveSpecialCharactersUsingCustomMethod(this string expression, bool removeSpecialLettersHavingASign = true)
{
var newCharacterWithSpace = " ";
var newCharacter = "";

// Return carriage handling
// ASCII LINE-FEED character (LF),
expression = expression.Replace("n", newCharacterWithSpace);
// ASCII CARRIAGE-RETURN character (CR)
expression = expression.Replace("r", newCharacterWithSpace);

// less than : used to redirect input, allowed in Unix filenames, see Note 1
expression = expression.Replace(@"<", newCharacter);
// greater than : used to redirect output, allowed in Unix filenames, see Note 1
expression = expression.Replace(@">", newCharacter);
// colon: used to determine the mount point / drive on Windows;
// used to determine the virtual device or physical device such as a drive on AmigaOS, RT-11 and VMS;
// used as a pathname separator in classic Mac OS. Doubled after a name on VMS,
// indicates the DECnet nodename (equivalent to a NetBIOS (Windows networking) hostname preceded by "\".).
// Colon is also used in Windows to separate an alternative data stream from the main file.
expression = expression.Replace(@":", newCharacter);
// quote : used to mark beginning and end of filenames containing spaces in Windows, see Note 1
expression = expression.Replace(@"""", newCharacter);
// slash : used as a path name component separator in Unix-like, Windows, and Amiga systems.
// (The MS-DOS command.com shell would consume it as a switch character, but Windows itself always accepts it as a separator.[16][vague])
expression = expression.Replace(@"/", newCharacter);
// backslash : Also used as a path name component separator in MS-DOS, OS/2 and Windows (where there are few differences between slash and backslash); allowed in Unix filenames, see Note 1
expression = expression.Replace(@"", newCharacter);
// vertical bar or pipe : designates software pipelining in Unix and Windows; allowed in Unix filenames, see Note 1
expression = expression.Replace(@"|", newCharacter);
// question mark : used as a wildcard in Unix, Windows and AmigaOS; marks a single character. Allowed in Unix filenames, see Note 1
expression = expression.Replace(@"?", newCharacter);
expression = expression.Replace(@"!", newCharacter);
// asterisk or star : used as a wildcard in Unix, MS-DOS, RT-11, VMS and Windows. Marks any sequence of characters
// (Unix, Windows, later versions of MS-DOS) or any sequence of characters in either the basename or extension
// (thus "*.*" in early versions of MS-DOS means "all files". Allowed in Unix filenames, see note 1
expression = expression.Replace(@"*", newCharacter);
// percent : used as a wildcard in RT-11; marks a single character.
expression = expression.Replace(@"%", newCharacter);
// period or dot : allowed but the last occurrence will be interpreted to be the extension separator in VMS, MS-DOS and Windows.
// In other OSes, usually considered as part of the filename, and more than one period (full stop) may be allowed.
// In Unix, a leading period means the file or folder is normally hidden.
expression = expression.Replace(@".", newCharacter);
// space : allowed (apart MS-DOS) but the space is also used as a parameter separator in command line applications.
// This can be solved by quoting, but typing quotes around the name every time is inconvenient.
//expression = expression.Replace(@"%", " ");
expression = expression.Replace(@"  ", newCharacter);

if (removeSpecialLettersHavingASign)
{
// Because then issues to zip
// More at : http://www.thesauruslex.com/typo/eng/enghtml.htm
expression = expression.Replace(@"ê", "e");
expression = expression.Replace(@"ë", "e");
expression = expression.Replace(@"ï", "i");
expression = expression.Replace(@"œ", "oe");
}

return expression;
}

手順2:まだ削除されていない無効な文字を確認します。

追加の検証手順、私は使用します Path.GetInvalidPathChars() まだ削除されていない潜在的な無効な文字を検出するための上記のメソッド。

public static bool ContainsAnyInvalidCharacters(this string path)
{
return (!string.IsNullOrEmpty(path) && path.IndexOfAny(Path.GetInvalidPathChars()) >= 0);
}

手順3:手順2で検出された特殊文字をすべて削除します。

そして最後に、このメソッドを最終ステップとして使用して、残っているものをすべて削除します。 (から 違法な文字をパスやファイル名から削除するには?):

public static string RemoveSpecialCharactersUsingFrameworkMethod(this string path)
{
return Path.GetInvalidFileNameChars().Aggregate(path, (current, c) => current.Replace(c.ToString(), string.Empty));
}

最初の手順でクリーンアップされなかった無効な文字をログに記録します。 「リーク」が検出されたらすぐに、その方法でカスタムメソッドを改善することにしました。頼りにできない Path.GetInvalidFileNameChars() 上記(MSDNから)で報告された次のステートメントのため:

「このメソッドから返される配列には、 ファイルおよびディレクトリで無効な完全な文字セット 名前。 」

それは理想的なソリューションではないかもしれませんが、私のアプリケーションのコンテキストと必要な信頼性のレベルを考えると、これは私が見つけた最良のソリューションです。


回答№4の場合は1

最終的に、いくつかの内部.NET実装を借用して組み合わせ、パフォーマンスの高いメソッドを作成しました。

/// <summary>Determines if the path contains invalid characters.</summary>
/// <remarks>This method is intended to prevent ArgumentException"s from being thrown when creating a new FileInfo on a file path with invalid characters.</remarks>
/// <param name="filePath">File path.</param>
/// <returns>True if file path contains invalid characters.</returns>
private static bool ContainsInvalidPathCharacters(string filePath)
{
for (var i = 0; i < filePath.Length; i++)
{
int c = filePath[i];

if (c == """ || c == "<" || c == ">" || c == "|" || c == "*" || c == "?" || c < 32)
return true;
}

return false;
}

私はそれを次のように使用しましたが、安全のためにtry / catchブロックでラップしました:

if ( !string.IsNullOrWhiteSpace(path) && !ContainsInvalidPathCharacters(path))
{
FileInfo fileInfo = null;

try
{
fileInfo = new FileInfo(path);
}
catch (ArgumentException)
{
}

...
}

回答№5の場合は0

私も遅すぎます。しかし、ユーザーがパスとして有効なものを入力したかどうかを検証することがタスクの場合、パスの組み合わせソリューションがあります。

Path.GetInvalidFileNameChars() ファイルに違法な文字のリストを返しますが、ディレクトリはファイルのルールに従いますが、セパレータ(システムから取得できる)とルート指定子(C:、検索から削除するだけです)。はい、 Path.GetInvalidFileNameChars() 完全なセットではありませんが、それらすべてを手動で検索するよりも優れています。

そう:

private static bool CheckInvalidPath(string targetDir)
{
string root;
try
{
root = Path.GetPathRoot(targetDir);
}
catch
{
// the path is definitely invalid if it has crashed
return false;
}

// of course it is better to cache it as it creates
// new array on each call
char[] chars = Path.GetInvalidFileNameChars();

// ignore root
for (int i = root.Length; i < targetDir.Length; i++)
{
char c = targetDir[i];

// separators are allowed
if (c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar)
continue;

// check for illegal chars
for (int j = 0; j < chars.Length; j++)
if (c == chars[j])
return false;
}

return true;
}

次のようなメソッドが見つかりました Path.GetFileName のようなパスではクラッシュしません C:* (これは完全に無効です)、例外ベースのチェックでも十分ではありません。クラッシュする唯一のもの Path.GetPathRoot 無効なルートです CC:someDir)。したがって、他のすべては手動で行う必要があります。