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

时间:2010-06-18 05:53:13

标签: c# .net validation path filesystems

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

文件路径可能或可能

10 个答案:

答案 0 :(得分:51)

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

另一种选择是直接与Path.GetInvalidPathChars核对。 E.g:

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

答案 1 :(得分:21)

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

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

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

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

答案 2 :(得分:8)

以下是您可能会使用的一些内容:

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

path参数包含无效字符,为空或仅包含空格。

答案 3 :(得分:3)

在尝试创建该文件之前,您无法确定。也许路径有效但安全设置不允许创建文件。可以告诉你路径是否真的有效的唯一实例是OS,所以为什么不尝试创建该文件捕获IOException,这表明出现了什么问题? Imho这是一种更简单的方法:假设输入是有效的,如果不是,则做一些事情,而不是做很多不必要的工作。

答案 4 :(得分:2)

你试过正则表达式吗?

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

应该有效

答案 5 :(得分:2)

尝试使用此方法,尝试涵盖所有可能的异常方案。它适用于几乎所有与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 less than 248 characters, and file names must be less 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;
}

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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

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

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

使用Regex.IsMatch运行它,你会得到一个bool,表明它是否有效。我认为正则表达式是可行的,因为该文件可能不存在。

答案 8 :(得分:0)

静态类System.IO.Path可以做你想要的。

答案 9 :(得分:0)

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

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

修改 请注意,如果path包含通配符('*'和'?'),则此函数不会引发异常,因为它们可以在搜索字符串中使用。