【问题标题】:Check whether a path is valid检查路径是否有效
【发布时间】:2011-09-06 02:30:07
【问题描述】:

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

问题是,我在 .Net API 中找不到任何东西。 由于 Windows 支持的格式和位置很多,我宁愿使用 MS-native 的东西。

由于该函数应该能够检查:

  • 相对路径 (./)
  • 绝对路径 (c:\tmp)
  • UNC 路径 (\some-pc\c$)
  • NTFS 限制,如完整路径 1024 个字符 - 如果我没记错的话,超出路径将使许多人无法访问文件 内部 Windows 功能。使用 Explorer 重命名仍然有效
  • 卷 GUID 路径:“\?\Volume{GUID}\somefile.foo

有人有这样的功能吗?

【问题讨论】:

标签: c# .net winapi path


【解决方案1】:

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

【讨论】:

  • 这为@"foo\bar\baz"返回false,这是一个完全有效的相对路径...
  • Thomas:你指定了什么 UriKind?您可以使用 Absolute、Relative 或 AbsoluteOrRelative。
  • 即使将 UriKind 设置为 Relative 或 AbsoluteOrRelative,它也不适用于 Thomas 提到的相对路径。我最终改用了 Patko 的答案,它适用于我的目的。
  • 我发现在使用 IsWellFormedUriString 时,诸如 \\computerName\Dir Name With Spaces\fileName 之类的路径会引发异常(与我最初的预期相反),因为空格未正确编码。我发现我可以只使用 Uri(string) 构造函数作为我的验证,因此,在验证之前不必正确编码字符串。
  • 在完美的文件路径上返回 false。
【解决方案2】:

【讨论】:

【解决方案3】:

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

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

【讨论】:

    【解决方案4】:
    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;
    }
    

    【讨论】:

    • 创建文件夹对于您认为只会为您检查字符串的布尔值来说是一个令人讨厌的副作用。
    【解决方案5】:

    你可以试试这个代码:

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

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

    【讨论】:

      【解决方案6】:

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

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

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

          • 这并不完全有效。 “C:\new.folder”在“C:\newfolder”时有效。不是。 '。'是路径/文件名的有效字符,但不在 uri 的末尾。
          【解决方案9】:

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

          string path = "yourPath";
          bool pathIsValid = null;
          try
          { 
              Path.GetFullPath(path);
              pathIsValid = true;
          }
          catch
          {
              pathIsValid = false;
          }
          

          【讨论】:

            【解决方案10】:
            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;
            }
            

            【讨论】:

            • x1 的目的是什么?
            【解决方案11】:

            【讨论】:

            • "[...] 不想检查文件是否存在!"
            • 测试目录是否存在,而不是它是否是有效路径(如果有适当的权限,它可能存在或被创建)
            • @Jason - 它不检查文件,只检查包含文件夹。
            • 但有效的目录路径仍然不存在。
            【解决方案12】:

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

            【讨论】:

              【解决方案13】:

              只需使用

              if (System.IO.Directory.Exists(path))
              {
                  ...
              }
              

              【讨论】:

              • 这不是 OP 要求的
              猜你喜欢
              • 2011-05-05
              • 2013-04-06
              • 1970-01-01
              • 2021-03-08
              • 2014-05-05
              • 1970-01-01
              • 1970-01-01
              • 2014-02-20
              • 1970-01-01
              相关资源
              最近更新 更多