检查路径是否有效


110

我只是想知道:我正在寻找一种验证给定路径是否有效的方法。 (注意:我不想检查文件是否存在!我只想证明路径的有效性-因此该位置是否可能存在文件)

问题是,我在.Net API中找不到任何内容。由于Windows支持多种格式和位置,因此我宁愿使用MS-native。

由于该功能应能够检查:

  • 相对路径(./)
  • 绝对路径(c:\ tmp)
  • UNC路径(\ some-pc \ c $)
  • NTFS-Limitations的完整路径为1024个字符-如果我没有记错,超过该路径将使许多内部Windows函数无法访问该文件。使用资源管理器重命名仍然有效
  • Volume GUID路径:“ \?\ Volume {GUID} \ somefile.foo

有人有这样的功能吗?


Answers:


58

尝试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.

9
这将返回false for @"foo\bar\baz",这是一个完全有效的相对路径...
Thomas Levesque 2012年

5
托马斯:您指定了什么UriKind?您可以使用Absolute,Relative或AbsoluteOrRelative。
DanGøranLunde

1
即使使用UriKind作为Relative或AbsoluteOrRelative,它也不适用于Thomas提到的相对路径。我最终改用了Patko的答案,它可以满足我的目的。
JohnnyM 2014年

1
我发现使用IsWellFormedUriString时,诸如\\ computerName \ Dir Name With Spaces \ fileName之类的路径会引发异常(与最初的预期相反),因为空格未正确编码。我发现我可以只使用Uri(string)构造函数作为验证,因此不必在验证之前正确编码字符串。
quintessential5

3
在完全正确的文件路径上返回false。
Evgeni Petrov'3


7
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

我下面的代码没有任何问题。(相对路径必须以“ /”或“ \”开头)。

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);

3

您可以尝试以下代码:

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

我不确定它是否涵盖所有情况...


2

我最接近的是尝试创建它,然后查看它是否成功。


2

这里有很多好的解决方案,但是由于没有一个,因此不检查路径是否根植于现有驱动器中,这是另一个驱动器

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;
}

此解决方案考虑相对路径。


1

从中获取无效字符,System.IO.Path.GetInvalidPathChars();并检查您的字符串(目录路径)是否包含这些字符。


3
这并不完全有效。“ C:\ new.folder”有效,而“ C:\ newfolder”有效。不是。'。' 是路径/文件名的有效字符,但不在uri的末尾。
claudekennilol 2013年


-2
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");

    if (string.IsNullOrWhiteSpace(path) || path.Length < 3)
    {
        return false;
    }

    if (!driveCheck.IsMatch(path.Substring(0, 3)))
    {
        return false;
    }

    var x1 = (path.Substring(3, path.Length - 3));
    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;
    }

    var driveLetterWithColonAndSlash = Path.GetPathRoot(path);

    if (!DriveInfo.GetDrives().Any(x => x.Name == driveLetterWithColonAndSlash))
    {
        return false;
    }

    return true;
}

1
x1的目的是什么?
JayJay


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.