通过 C# 确定字符串是不是是有效的文件路径

Posted

技术标签:

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

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

文件路径可能不存在

【问题讨论】:

您是说您有一个看起来像路径的字符串,并且该文件是否实际存在,您想知道给定“路径”处的文件是否存在?如果路径有效,即使该位置没有文件? How check if given string is legal (allowed) file name under Windows? 的可能重复项 如果您关心的是更一般地测试字符串是否可以表示文件文件夹,请参阅this answer 或this related answer。 【参考方案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、规范化等的所有规则。

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

Wikipedia - Filename 了解不同文件系统使用的规则概览 Naming Files, Paths, and Namespaces 用于 Windows 特定规则

【讨论】:

【参考方案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 可以满足您的要求。

【讨论】:

以上是关于通过 C# 确定字符串是不是是有效的文件路径的主要内容,如果未能解决你的问题,请参考以下文章

检查字符串是不是是有效的 Windows 目录(文件夹)路径

Nodejs检查给定的字符串是不是是有效的文件系统路径而不实际检查文件系统

VC怎么通过绝对路径确定一个文件或者文件夹是不是存在,如果是文件存在,怎么获得该文件的大小

C# + 访问错误:不是有效的文件名

路径部分中带有 // 的 URL 是不是有效?

如何确定字符串是 C# 中的有效 IPv4 还是 IPv6 地址?