【问题标题】:Determine via C# whether a string is a valid file path通过 C# 确定字符串是否是有效的文件路径
【发布时间】:2011-03-05 07:02:31
【问题描述】:

我想知道如何判断字符串是否是有效的文件路径。

文件路径可能不存在

【问题讨论】:

标签: c# .net validation path filesystems


【解决方案1】:

您可以使用FileInfo 构造函数。如果“文件名为空、仅包含空格或包含无效字符”,它将抛出 ArgumentException。它还可以抛出 SecurityException 或 UnauthorizedAccessException,如果您只关心格式,我认为您可以忽略它们。

另一种选择是直接检查Path.GetInvalidPathChars。例如:

boolean possiblePath = pathString.IndexOfAny(Path.GetInvalidPathChars()) == -1;

【讨论】:

  • FWIW,这将返回误报。您还需要检查权限,并且文件夹/文件名不是非法的之一(en.wikipedia.org/wiki/DOS#Reserved_device_names)。
  • new FileInfo("test") 完全有效,但不是文件。
  • @Julien 如果您没有传入完整路径,它会将其视为来自Directory.GetCurrentDirectory() 返回的任何内容的相对路径。因此,如果您在C:\Temp 工作并调用new FileInfo("test");,则FullName 属性将为C:\Temp\test
  • FileInfo 构造函数也会抛出 NotSupportedException
【解决方案2】:

100% 准确地检查路径的字符串格式非常困难,因为它取决于使用它的文件系统(以及网络协议,如果它不在同一台计算机上)。

即使在 Windows 甚至 NTFS 中,它也并不简单,因为它仍然依赖于 .NET 在后台使用的 API 与内核通信。

由于当今大多数文件系统都支持 unicode,因此可能还需要检查正确编码的 unicode、规范化等的所有规则。

我要做的只是进行一些基本检查,然后在使用路径后正确处理异常。有关可能的规则,请参阅:

【讨论】:

    【解决方案3】:

    这里有一些你可能会用到的东西:

    • 检查驱动器是否正确(例如在一台计算机上存在驱动器 X:\,但在您的计算机上不存在):使用 Path.IsPathRooted 查看它是否不是相对路径,然后使用来自 Environment.GetLogicalDrives() 的驱动器查看您的路径是否包含有效驱动器之一。
    • 要检查有效字符,您有两种方法:Path.GetInvalidFileNameChars()Path.GetInvalidPathChars(),它们不完全重叠。您还可以使用Path.GetDirectoryName(path)Path.GetFileName(fileName) 与您的输入名称,如果是throw an exception

    路径参数包含无效字符、为空或仅包含空格。

    【讨论】:

      【解决方案4】:

      在您尝试创建该文件之前,您无法确定。也许路径是有效的,但安全设置不允许创建文件。唯一可以告诉您路径是否真正有效的实例是操作系统,那么您为什么不尝试创建该文件并捕获表明它无效的IOException?以我的拙见,这是一种方法:假设输入有效,使用它,并在无效时捕获IOException

      【讨论】:

      • 这个问题对我来说很清楚,尝试创建该文件并不能回答这个问题。 字符串是有效的文件路径吗?
      【解决方案5】:

      你试过正则表达式吗?

      ^([a-zA-Z]\:)(\\[^\\/:*?<>"|]*(?<![ ]))*(\.[a-zA-Z]{2,6})$
      

      应该工作

      【讨论】:

      • 他从来没有说过绝对路径,文件扩展名长度没有限制,而且不便携。
      • 有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 -杰米·扎温斯基
      【解决方案6】:

      试试这个方法,它会尝试覆盖所有可能的异常情况。它适用于几乎所有与 Windows 相关的路径。

      /// <summary>
      /// Validate the Path. If path is relative append the path to the project directory by
      /// default.
      /// </summary>
      /// <param name="path">Path to validate</param>
      /// <param name="RelativePath">Relative path</param>
      /// <param name="Extension">If want to check for File Path</param>
      /// <returns></returns>
      private static bool ValidateDllPath(ref string path, 
                                              string RelativePath = "", 
                                              string Extension = "")
      {
        // Check if it contains any Invalid Characters.
        if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1)
        {
          try
          {
            // If path is relative take %IGXLROOT% as the base directory
            if (!Path.IsPathRooted(path))
            {
              if (string.IsNullOrEmpty(RelativePath))
              {
                // Exceptions handled by Path.GetFullPath
                // ArgumentException path is a zero-length string, contains only white space,
                // or contains one or more of the invalid characters defined in 
                // GetInvalidPathChars. -or- The system could not retrieve the absolute path.
                // 
                // SecurityException The caller does not have the required permissions.
                // 
                // ArgumentNullException path is null.
                // 
                // NotSupportedException path contains a colon (":") that is not part of a
                // volume identifier (for example, "c:\"). 
                // PathTooLongException The specified path, file name, or both exceed the
                // system-defined maximum length. For example, on Windows-based platforms,
                // paths must be fewer than 248 characters, and file names must be fewer than
                // 260 characters.
      
                // RelativePath is not passed so we would take the project path 
                path = Path.GetFullPath(RelativePath);
      
              }
              else
              {
                // Make sure the path is relative to the RelativePath and not our project
                // directory
                path = Path.Combine(RelativePath, path);
              }
            }
      
            // Exceptions from FileInfo Constructor:
            //   System.ArgumentNullException:
            //     fileName is null.
            //
            //   System.Security.SecurityException:
            //     The caller does not have the required permission.
            //
            //   System.ArgumentException:
            //     The file name is empty, contains only white spaces, or contains invalid
            //     characters.
            //
            //   System.IO.PathTooLongException:
            //     The specified path, file name, or both exceed the system-defined maximum
            //     length. For example, on Windows-based platforms, paths must be less than
            //     248 characters, and file names must be less than 260 characters.
            //
            //   System.NotSupportedException:
            //     fileName contains a colon (:) in the middle of the string.
            FileInfo fileInfo = new FileInfo(path);
      
            // Exceptions using FileInfo.Length:
            //   System.IO.IOException:
            //     System.IO.FileSystemInfo.Refresh() cannot update the state of the file or
            //     directory.
            //
            //   System.IO.FileNotFoundException:
            //     The file does not exist.-or- The Length property is called for a directory.
            bool throwEx = fileInfo.Length == -1;
      
            // Exceptions using FileInfo.IsReadOnly:
            //   System.UnauthorizedAccessException:
            //     Access to fileName is denied.
            //     The file described by the current System.IO.FileInfo object is read-only.
            //     -or- This operation is not supported on the current platform.
            //     -or- The caller does not have the required permission.
            throwEx = fileInfo.IsReadOnly;
      
            if (!string.IsNullOrEmpty(Extension))
            {
              // Validate the Extension of the file.
              if (Path.GetExtension(path).Equals(Extension,
                  StringComparison.InvariantCultureIgnoreCase))
              {
                // Trim the Library Path
                path = path.Trim();
                return true;
              }
              else
              {
                return false;
              }
            }
            else
            {
              return true;
      
            }
          }
          catch (ArgumentNullException)
          {
            //   System.ArgumentNullException:
            //     fileName is null.
          }
          catch (System.Security.SecurityException)
          {
            //   System.Security.SecurityException:
            //     The caller does not have the required permission.
          }
          catch (ArgumentException)
          {
            //   System.ArgumentException:
            //     The file name is empty, contains only white spaces, or contains invalid
            //     characters.
          }
          catch (UnauthorizedAccessException)
          {
            //   System.UnauthorizedAccessException:
            //     Access to fileName is denied.
          }
          catch (PathTooLongException)
          {
            //   System.IO.PathTooLongException:
            //     The specified path, file name, or both exceed the system-defined maximum
            //     length. For example, on Windows-based platforms, paths must be less than
            //     248 characters, and file names must be less than 260 characters.
          }
          catch (NotSupportedException)
          {
            //   System.NotSupportedException:
            //     fileName contains a colon (:) in the middle of the string.
          }
          catch (FileNotFoundException)
          {
            // System.FileNotFoundException
            //  The exception that is thrown when an attempt to access a file that does not
            //  exist on disk fails.
          }
          catch (IOException)
          {
            //   System.IO.IOException:
            //     An I/O error occurred while opening the file.
          }
          catch (Exception)
          {
            // Unknown Exception. Might be due to wrong case or nulll checks.
          }
        }
        else
        {
          // Path contains invalid characters
        }
        return false;
      }
      

      【讨论】:

        【解决方案7】:
        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;
              }
              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 directoryInfo = new DirectoryInfo(Path.GetFullPath(path));
              try
              {
                if (!directoryInfo.Exists)
                {
                  directoryInfo.Create();
                }
              }
              catch (Exception ex)
              {
                if (Log.IsErrorEnabled)
                {
                  Log.Error(ex.Message);
                }
                return false;
              }`enter code here`
        
              return true;
            }
        

        【讨论】:

        • 这对我有用.. 甚至 PC 中不存在位置
        【解决方案8】:

        我在 Dmitry Borysov 的 regexlib.com (http://regexlib.com/REDetails.aspx?regexp_id=345) 上找到了这个。

        “文件名验证器。验证 UNC (\server\share\file) 和常规 MS 路径 (c:\file)”

        ^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?))\\)*[^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?$
        

        使用 Regex.IsMatch 运行它,您将得到一个布尔值,指示它是否有效。我认为正则表达式是可行的方法,因为该文件可能不存在。

        【讨论】:

          【解决方案9】:

          您可以在 try catch 语句中简单地使用 Path.Combine():

          string path = @" your path ";
          try
          {
              Path.Combine(path);
          }
          catch
          {
              MessageBox.Show("Invalid path");
          }
          

          编辑: 请注意,如果路径包含通配符(“*”和“?”),此函数不会引发异常,因为它们可用于搜索字符串。

          【讨论】:

          • 当我的路径是“非法的”时,这实际上并没有捕捉到
          【解决方案10】:

          静态类 System.IO.Path 可以满足您的要求。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-04-02
            • 2011-03-09
            • 2022-12-15
            • 2010-10-21
            • 1970-01-01
            • 2018-05-23
            • 1970-01-01
            • 2014-12-05
            相关资源
            最近更新 更多