我正在尝试确定用户输入的字符串是否有效用于表示文件夹的路径。有效,我的意思是格式正确。
在我的应用程序中,该文件夹代表一个安装目标。如果文件夹路径 有效,我想确定该文件夹是否存在,如果不存在则创建它。
我目前正在使用IO.Directory.Exists( String path )
。我发现这很好用,除非用户没有正确格式化字符串。发生这种情况时,此方法将返回false,表示该文件夹不存在。但这是一个问题,因为我之后无法创建该文件夹。
从我的Google搜索中,我发现了一个使用正则表达式检查格式是否正确的建议。我没有正则表达式的经验,我想知道这是否是一种可行的方法。这是我发现的:
Regex r = new Regex( @"^(([a-zA-Z]\:)|(\\))(\\{1}|((\\{1})[^\\]([^/:*?<>""|]*))+)$" );
return r.IsMatch( path );
正则表达式测试与Directory.Exists()
结合使用,会给我一个足够好的方法来检查路径是否有效以及是否存在?我知道这会因操作系统和其他因素而有所不同,但该计划仅针对 Windows 用户。
答案 0 :(得分:103)
致电Path.GetFullPath
;如果路径无效,它将抛出异常。
要禁止相对路径(例如Word
),请致电Path.IsPathRooted
。
答案 1 :(得分:19)
我实际上不同意SLaks。那个解决方案对我不起作用。异常没有按预期发生。但是这段代码对我有用:
if(System.IO.Directory.Exists(path))
{
...
}
答案 2 :(得分:10)
Path.GetFullPath仅提供以下例外情况
ArgumentException路径是一个零长度字符串,仅包含白色 空格,或包含一个或多个定义的无效字符 GetInvalidPathChars。 - 或 - 系统无法检索绝对路径。
SecurityException调用者没有所需的权限。
ArgumentNullException路径为空。
NotSupportedException路径包含不属于的冒号(&#34;:&#34;) 卷标识符(例如,&#34; c:\&#34;)。
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;
}
答案 3 :(得分:8)
这是一个利用Path.GetFullPath中建议使用the answer by @SLaks的解决方案。
在我在此处包含的代码中,请注意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;
}
答案 4 :(得分:6)
使用此代码
string DirectoryName = "Sample Name For Directory Or File";
Path.GetInvalidFileNameChars().Where(x => DirectoryName.Contains(x)).Count() > 0 || DirectoryName == "con"
答案 5 :(得分: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;
}
答案 6 :(得分:2)
我对这段代码没有任何问题:
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);
这些都会成真:
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", false);
答案 7 :(得分:2)
一种更简单的独立于操作系统的解决方案:
继续并尝试创建实际目录; 如果出现问题或名称无效,操作系统将自动进行投诉,并抛出代码。
public static class PathHelper
{
public static void ValidatePath(string path)
{
if (!Directory.Exists(path))
Directory.CreateDirectory(path).Delete();
}
}
用法:
try
{
PathHelper.ValidatePath(path);
}
catch(Exception e)
{
// handle exception
}
Directory.CreateDirectory()
将在以下所有情况下自动抛出:
System.IO.IOException:
path指定的目录是一个文件。 -或-网络名称未知。System.UnauthorizedAccessException:
来电者没有 所需的权限。System.ArgumentException:
path是零长度的字符串,包含 仅空白,或包含一个或多个无效字符。您 可以使用来查询无效字符 System.IO.Path.GetInvalidPathChars方法。 -或-路径前缀 只能包含或包含一个冒号(:)。System.ArgumentNullException:
路径为空。System.IO.PathTooLongException:
指定的路径,文件名或 都超过了系统定义的最大长度。System.IO.DirectoryNotFoundException:
指定的路径无效 (例如,它在未映射的驱动器上)。System.NotSupportedException:
路径包含冒号(:) 而不是驱动器标签(“ C:”)的一部分。