2010-06-29 33 views
60

我想确定一个用户输入的字符串是否有效表示一个文件夹的路径。通过有效,我的意思是格式正确。检查一个字符串是否是一个有效的Windows目录(文件夹)路径

在我的应用程序中,该文件夹代表安装目标。假设文件夹路径有效,我想确定文件夹是否存在,如果不存在,则创建它。我正在使用IO.Directory.Exists(String path)。我发现这工作正常,除非用户没有正确格式化字符串。发生这种情况时,此方法将返回false,表示该文件夹不存在。但这是一个问题,因为我以后无法创建文件夹。

从我的谷歌搜索中,我发现了一个建议,使用正则表达式来检查格式是否正确。我对正则表达式没有经验,并且想知道这是否可行。这里是我的发现:

Regex r = new Regex(@"^(([a-zA-Z]\:)|(\\))(\\{1}|((\\{1})[^\\]([^/:*?<>""|]*))+)$"); 
return r.IsMatch(path); 

会结合正则表达式测试与Directory.Exists(),给我一个不够好方法来检查路径是否有效,它是否存在?我知道这将随操作系统和其他因素而变化,但该程序仅针对Windows用户。

+1

如果它不会在Directory.Exists re之后创建目录会变成错误的,这不是一个很好的指示,说明用户提供了错误的输入吗? – 2010-06-29 00:34:55

+1

http://stackoverflow.com/questions/3067479/figuring-out-whether-string-is-valid-file-path – 2010-06-29 00:35:48

+0

http://stackoverflow.com/questions/422090/in-c-check-that-filename - 可能是有效的,不是那个 - 存在 – 2010-06-29 00:36:45

回答

83

致电Path.GetFullPath;如果路径无效,它会引发异常。

要禁止相对路径(例如Word),请致电Path.IsPathRooted

+0

我知道有更简单的东西! 谢谢,我没有想到路径相关问题。 – Dinoo 2010-06-29 01:08:45

+2

谢谢SLaks。我看到很多重复的内容,并且在不止一次的情况下做了很多谷歌搜索,但这是我第一次看到这个特定问题的一个很好的答案。 – 2010-06-29 01:18:18

+0

Path.GetFullPath(“con.txt”)working ...但这不是有效的文件名 – Evgeny 2011-04-30 22:59:29

6

使用此代码

string DirectoryName = "Sample Name For Directory Or File"; 
Path.GetInvalidFileNameChars().Where(x => DirectoryName.Contains(x)).Count() > 0 || DirectoryName == "con" 
+4

稍短代码完成同样的事情: 'Path.GetInvalidFileNameChars()。Any(DirectoryName.Contains)|| DirectoryName ==“con”' – bsegraves 2012-10-15 18:06:02

+3

它不只是“con”你必须照顾.. – nawfal 2013-06-12 12:36:17

+1

@nawfal的确。从MSDN上的[命名文件,路径和命名空间](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v = vs.85).aspx):*“请勿使用以下为文件名称的保留名称:CON,PRN,AUX,NUL,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7 ,LPT8和LPT9,同时避免使用这些名称,后面紧跟一个扩展名;例如,不建议使用NUL.txt。有关详细信息,请参见[命名空间](https://msdn.microsoft.com/en-us/library /windows/desktop/aa365247(v=vs.85).aspx#namespaces)."* – DavidRR 2016-12-09 19:58:39

18

我实际上SLaks不同意。该解决方案对我无效。异常没有按预期发生。但是这个代码为我工作:

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

一个有效的路径不一定是一个存在的目录......这正是这里问的问题 – Benlitz 2013-09-06 08:21:59

+1

问题是关于验证的路径字符串,可能不存在的路径。 – 2013-12-02 01:11:09

+0

我认为这种方式是正确的。不应该有例外情况。该方法还会检查给定路径中的不正确字符。 – 2016-07-07 13:44:17

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

Path.GetFullPath,给出以下的例外只有

ArgumentException的路径是一个零长度字符串,仅包含白色 空间,或者包含一个或更多在 GetInvalidPathChars中定义的无效字符。 - 或者 - 系统无法检索绝对路径。

SecurityException调用者没有所需的权限。

ArgumentNullException path为null。

NotSupportedException路径包含冒号(“:”),它不是 卷标识符(例如“c:\”)的一部分。

PathTooLongException指定的路径,文件名或两者超过系统定义的最大长度的 。例如,在基于Windows的 平台上,路径必须少于248个字符,文件名必须为 少于260个字符。

替代的方法是使用以下内容:

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

下面是利用如在the answer by @SLaks推荐使用Path.GetFullPath的溶液。

在,我这里有包括代码,请注意IsValidPath(string path)设计使得主叫方担心异常处理

您也可能会发现它调用的方法TryGetFullPath(...),当您希望安全地尝试获取绝对路径时,它也有其优点。

/// <summary> 
/// Gets a value that indicates whether <paramref name="path"/> 
/// is a valid path. 
/// </summary> 
/// <returns>Returns <c>true</c> if <paramref name="path"/> is a 
/// valid path; <c>false</c> otherwise. Also returns <c>false</c> if 
/// the caller does not have the required permissions to access 
/// <paramref name="path"/>. 
/// </returns> 
/// <seealso cref="Path.GetFullPath"/> 
/// <seealso cref="TryGetFullPath"/> 
public static bool IsValidPath(string path) 
{ 
    string result; 
    return TryGetFullPath(path, out result); 
} 

/// <summary> 
/// Returns the absolute path for the specified path string. A return 
/// value indicates whether the conversion succeeded. 
/// </summary> 
/// <param name="path">The file or directory for which to obtain absolute 
/// path information. 
/// </param> 
/// <param name="result">When this method returns, contains the absolute 
/// path representation of <paramref name="path"/>, if the conversion 
/// succeeded, or <see cref="String.Empty"/> if the conversion failed. 
/// The conversion fails if <paramref name="path"/> is null or 
/// <see cref="String.Empty"/>, or is not of the correct format. This 
/// parameter is passed uninitialized; any value originally supplied 
/// in <paramref name="result"/> will be overwritten. 
/// </param> 
/// <returns><c>true</c> if <paramref name="path"/> was converted 
/// to an absolute path successfully; otherwise, false. 
/// </returns> 
/// <seealso cref="Path.GetFullPath"/> 
/// <seealso cref="IsValidPath"/> 
public static bool TryGetFullPath(string path, out string result) 
{ 
    result = String.Empty; 
    if (String.IsNullOrWhiteSpace(path)) { return false; } 
    bool status = false; 

    try 
    { 
     result = Path.GetFullPath(path); 
     status = true; 
    } 
    catch (ArgumentException) { } 
    catch (SecurityException) { } 
    catch (NotSupportedException) { } 
    catch (PathTooLongException) { } 

    return status; 
} 
0

我还没有与此代码的任何问题:

private bool IsValidPath(string path, bool exactPath = true) 
{ 
    bool isValid = true; 

    try 
    { 
     string fullPath = Path.GetFullPath(path); 

     if (exactPath) 
     { 
      string root = Path.GetPathRoot(path); 
      isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false; 
     } 
     else 
     { 
      isValid = Path.IsPathRooted(path); 
     } 
    } 
    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"); 
IsValidPath("abc"); 
IsValidPath("abc", false); 

而这些将返回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~`[email protected]#$%^&()_-+={[}];',.g"); 
IsValidPath(@"C:\\\\\abc////////defg"); 
IsValidPath(@"/abc", false); 
相关问题