web-dev-qa-db-ja.com

パスが有効かどうかを確認します

私はただ疑問に思っています。特定のパスが有効かどうかを検証する方法を探しています。 (注:ファイルが存在するかどうかをチェックしたくない!パスの有効性を証明したいだけ-ファイルがその場所に存在する可能性がある場合)

問題は、.Net APIに何も見つからないことです。 Windowsがサポートする多くの形式と場所のために、私はむしろMSネイティブのものを使用します。

関数は以下に対してチェックできるはずです:

  • 相対パス(./)
  • 絶対パス(c:\ tmp)
  • UNCパス(\ some-pc\c $)
  • フルパス1024文字などのNTFS制限-パスを超えて間違えないと、多くの内部Windows機能でファイルにアクセスできなくなります。 Explorerで名前を変更しても機能します
  • ボリュームGUIDパス: "\?\ Volume {GUID}\somefile.foo

誰もがこのような機能を持っていますか?

97
Corelgott

Uri.IsWellFormedUriString() を試してください:

  • 文字列は正しくエスケープされていません。

    http://www.example.com/path???/file name
    
  • 文字列は、暗黙的なファイルUriを表す絶対Uriです。

    c:\\directory\filename
    
  • 文字列は絶対URIであり、パスの前にスラッシュがありません。

    file://c:/directory/filename
    
  • 文字列には、スラッシュとして扱われる場合でも、エスケープされていないバックスラッシュが含まれます。

    http:\\Host/path/file
    
  • 文字列は階層的な絶対Uriを表し、「://」は含まれません。

    www.example.com/path/file
    
  • Uri.Schemeのパーサーは、元の文字列が整形式ではなかったことを示しています。

    The example depends on the scheme of the URI.
    
56
abatishchev
27
Patko
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;
    string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
    strTheseAreInvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;

    DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(path));
    if (!dir.Exists)
        dir.Create();
    return true;
}
7
Alex Jolig

以下のコードに問題はありません。 (相対パスは「/」または「\」で始まる必要があります)。

private bool IsValidPath(string path, bool allowRelativePaths = false)
{
    bool isValid = true;

    try
    {
        string fullPath = Path.GetFullPath(path);

        if (allowRelativePaths)
        {
            isValid = Path.IsPathRooted(path);
        }
        else
        {
            string root = Path.GetPathRoot(path);
            isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false;
        }
    }
    catch(Exception ex)
    {
        isValid = false;
    }

    return isValid;
}

たとえば、これらはfalseを返します。

IsValidPath("C:/abc*d");
IsValidPath("C:/abc?d");
IsValidPath("C:/abc\"d");
IsValidPath("C:/abc<d");
IsValidPath("C:/abc>d");
IsValidPath("C:/abc|d");
IsValidPath("C:/abc:d");
IsValidPath("");
IsValidPath("./abc");
IsValidPath("./abc", true);
IsValidPath("/abc");
IsValidPath("abc");
IsValidPath("abc", true);

そして、これらはtrueを返します。

IsValidPath(@"C:\\abc");
IsValidPath(@"F:\FILES\");
IsValidPath(@"C:\\abc.docx\\defg.docx");
IsValidPath(@"C:/abc/defg");
IsValidPath(@"C:\\\//\/\\/\\\/abc/\/\/\/\///\\\//\defg");
IsValidPath(@"C:/abc/def~`!@#$%^&()_-+={[}];',.g");
IsValidPath(@"C:\\\\\abc////////defg");
IsValidPath(@"/abc", true);
IsValidPath(@"\abc", true);
5
Dao Seeker

このコードを試すことができます:

try
{
  Path.GetDirectoryName(myPath);
}
catch
{
  // Path is not valid
}

私はそれがすべてのケースをカバーするかどうかわかりません...

2
Nimrod

ここには多くの優れたソリューションがありますが、既存のドライブにパスがルートされているかどうかを確認する方法はありません:

private bool IsValidPath(string path)
{
    // Check if the path is rooted in a driver
    if (path.Length < 3) return false;
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;

    // Check if such driver exists
    IEnumerable<string> allMachineDrivers = DriveInfo.GetDrives().Select(drive => drive.Name);
    if (!allMachineDrivers.Contains(path.Substring(0, 3))) return false;

    // Check if the rest of the path is valid
    string InvalidFileNameChars = new string(Path.GetInvalidPathChars());
    InvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(InvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;
    if (path[path.Length - 1] == '.') return false;

    return true;
}

このソリューションはnot相対パスを考慮します。

1
Gark Garcia
1
markpsmith

私が最も近づいたのは、それを作成しようとし、成功するかどうかを確認することです。

1
Martijn

System.IO.Path.GetInvalidPathChars();から無効な文字を取得し、文字列(ディレクトリパス)にそれらが含まれているかどうかを確認します。

1
Umesh CHILAKA