检查路径是否有效

本文关键字:有效 是否 路径 检查 | 更新日期: 2023-09-27 17:58:12

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

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

由于该功能应该能够检查:

  • 相对路径(./)
  • 绝对路径(c:''tmp)
  • UNC路径(''some pc''c$)
  • NTFS限制,如完整路径1024个字符-如果我没有弄错,超过路径将使许多人无法访问文件内部Windows功能。使用资源管理器重命名它仍然有效
  • 卷GUID路径:"''?''Volume{GUID}''somefile.foo

有人有这样的功能吗?

检查路径是否有效

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

或者使用C#中建议的FileInfo,检查文件名是否有效(不存在)。

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

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

这些都是真的:

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

您可以尝试以下代码:

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

我不确定它是否涵盖了所有的情况。。。

这里有很多好的解决方案,但没有一个可以检查路径是否植根于现有驱动器这里有另一个:

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

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

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

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

这接受了一个可能等同于的有效相对路径的路径

string path = "yourPath";
bool pathIsValid = null;
try
{ 
    Path.GetFullPath(path);
    pathIsValid = true;
}
catch
{
    pathIsValid = false;
}
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;
}
目录是否存在?

您可以尝试将Path.IsPathRooted()与Path.GetInvalidFileNameChars()结合使用,以确保路径正常。