检查path是否有效
我只是想知道:我正在寻找一种方法来validation给定的path是否有效。 (注:我不想检查一个文件是否存在!我只想certificatepath的有效性 – 所以如果一个文件可能存在的位置) 。
问题是,我在.Net API中找不到任何东西。 由于Windows支持多种格式和位置,我宁愿使用MS-native。
由于该function应该能够检查:
- 相对path(./)
- 绝对path(c:\ tmp)
- UNC-Pathes(\ some-pc \ c $)
- 像完整path1024个字符的NTFS限制 – 如果我没有被误认为超出path,将使许多内部Windowsfunction无法访问文件。 用Explorer重命名仍然有效
- 卷GUIDpath:“\?\卷{GUID} \ somefile.foo
有没有人有这样的function?
试试Uri.IsWellFormedUriString()
:
-
该string没有正确转义。
http://www.example.com/path???/file name
-
该string是一个绝对的Uri,代表一个隐式文件Uri。
c:\\directory\filename
-
该string是绝对URI,在path之前缺less一个斜线。
file://c:/directory/filename
-
该string包含未转义的反斜杠,即使它们被视为正斜杠。
http:\\host/path/file
-
该string表示层次绝对的Uri,不包含“://”。
www.example.com/path/file
-
Uri.Scheme的parsing器指示原始string格式不正确。
The example depends on the scheme of the URI.
或者使用In C#中build议的FileInfo 检查文件名可能是有效的(不是它存在) 。
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; }
我最近来到的是试图创造它,看看它是否成功。
你可以试试这个代码:
try { Path.GetDirectoryName(myPath); } catch { // Path is not valid }
我不确定它涵盖了所有的情况
Directory.Exists?
从System.IO.Path.GetInvalidPathChars();
获取无效字符System.IO.Path.GetInvalidPathChars();
并检查你的string(目录path)是否包含这些。
试试这个方法
/// <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; }
private bool IsValidPath(string path) { 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; } var x1 = (path.Substring(3, path.Length - 3)); 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; } var driveLetterWithColonAndSlash = Path.GetPathRoot(path); if (!DriveInfo.GetDrives().Any(x => x.Name == driveLetterWithColonAndSlash)) { return false; } return true; }
using System; using System.IO; using System.Text.RegularExpressions; public class ControlFullPathNameValidity { public static void Main() { int counter = 0; int position = 0; char slash = '\\'; //char[] getInvalidPathChars = Path.GetInvalidPathChars();//I could not make it work char[] getInvalidPathChars = { '<', '>', ':', ',', '"', '/', '|', '?', '*', '.', '[', ']', '=' }; string fullPathFileName = string.Empty; string[] getLogicalDrives = Directory.GetLogicalDrives(); string directoryPathSubStr = string.Empty, fileNameSubStr = string.Empty; string yn = string.Empty; bool tf = true; foreach (var item in getInvalidPathChars) Console.Write(item + " "); Regex fileNameSubStrRegexControl = new Regex(@"^[a-zA-Z]+$"); Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write("Undesired path name characters: "); foreach (var item in getInvalidPathChars) Console.Write(item + " "); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Cyan; do { while (true) { Console.WriteLine("\nPlease, type the desired full path name of the new file: "); fullPathFileName = @Console.ReadLine(); //Primary checks if (fullPathFileName.Length < 8) { //1st Test Passed Console.Write("Invalid full name: The full file path name typed\n" + "contains less than eight characters. Retry (y/n)? "); fullPathFileName = string.Empty; break; } else { for (counter = 0; counter < getLogicalDrives.Length; ++counter) if (fullPathFileName.Remove(1) == getLogicalDrives[counter].Remove(1)) { //2nd Test passed. //Console.WriteLine("Hosting Logical Drive: {0}", getLogicalDrives[counter]); counter = 0; break; } if (counter != 0) { Console.Write("Error: The logical directory provided corresponds to\n" + "no physical disk drive of this machine. Retry (y/n)? "); fullPathFileName = string.Empty; break; } } if (!fullPathFileName.Contains(@"\")) { Console.Write("Invalid name: Full name contains no slash at all. Retry (y/n)? "); fullPathFileName = string.Empty; break; } else if (fullPathFileName.Substring(1, 2) != @":\") { Console.Write("Invalid name: The second or/and third characters of the\n" + "full file path are not of \":\\\" format. Retry (y/n)? "); fullPathFileName = string.Empty; break; } else if (fullPathFileName.Substring(4, 1) == @"\") { Console.WriteLine("*Invalid name: Slash found right\n" + "after slash. Retry (y/n)? "); fullPathFileName = string.Empty; break; } //Let us break the fullPathFileName into two substrings directoryPathSubStr = fullPathFileName.Remove(fullPathFileName.LastIndexOf(@"\")) + "\\";//Directory path fileNameSubStr = fullPathFileName.Remove(0, fullPathFileName.LastIndexOf(@"\") + 1);//File name fullPathFileName = string.Empty;//How do we kill this variable? It is not useful anymore. //Let us examine the validity of the 1st substring (Directory path) position = 2; while (directoryPathSubStr.IndexOf(slash, position + 1) != -1) { /*Sorry. I cannot optimize this while_block any further. I think that it is susceptible of more optimization. In the future, I will try to start the block with while(subStr1.IndexOf(slash, position + 1) + 1 < subStr1.Length) */ if (directoryPathSubStr.Substring(directoryPathSubStr.IndexOf(slash, position + 1) - 1, 1) == @"\") { Console.Write("Invalid name: Slash found right\n" + "after slash. Retry (y/n)? "); tf = false; break; } string currentSubDirectory = directoryPathSubStr.Substring(position + 1, directoryPathSubStr.IndexOf(slash, position + 1) - position - 1); // foreach (var item in getInvalidPathChars) //Not quite proper. I could not find any foreach inside_counter for (int i = 0; i < getInvalidPathChars.Length; ++i) { if (directoryPathSubStr.Substring(position + 1, directoryPathSubStr.IndexOf(slash, position + 1) - position - 1).Contains(getInvalidPathChars[i].ToString())) { Console.Write("Invalid name: Invalid character <{0}> in subdirectory\nstring '{1}'. Retry (y/n)? ", getInvalidPathChars[i], currentSubDirectory, position + directoryPathSubStr.Substring(position + 1, directoryPathSubStr.IndexOf(slash, position + 1) - position - 1).IndexOf(getInvalidPathChars[i].ToString()) + 1); tf = false; break; } } if (!tf) break; position = directoryPathSubStr.IndexOf(slash, position + 1); } if (!tf) break; //Now, let us examine the validity of the 2nd substring /*if (fileNameSubStr.Length < 5) { //This block cannot run! Console.Write("Invalid File Name: the name contains less\n" + "than five characters. Retry (y/n)? "); break; } else*/ if (!fileNameSubStr.Contains(".")) { //Check if the full file name contains no punctuation Console.Write("Invalid File Name: No punctuation in\n" + "file extension name. Retry (y/n)? "); break; } else if (fileNameSubStr.IndexOf(".") != fileNameSubStr.Length - 4) { //Check if the punctuation is exactly where it is supposed to be (4 positions before end) Console.Write("Invalid File Name: No proper punctuation in the file\n" + "extension name (ie fileName.dat). Retry (y/n)? "); break; } else if (fileNameSubStr.Remove(0, fileNameSubStr.LastIndexOf(".")).Length - 1 != 3) { /*OPTIMIZATION: This block won't run */ //Check if the file extension contains exactly 3 characters Console.Write("Invalid File Name: The extension does not strictly\n" + "contain three letters (az or AZ). Retry (y/n)? "); break; } else if (!fileNameSubStrRegexControl.IsMatch(fileNameSubStr.Remove(0, fileNameSubStr.LastIndexOf(".") + 1))) { /*OPTIMIZATION: This block won't run */ //Check if the file extension contains only letters Console.Write("The end of file extension name does contain three characters, but\n" + "not all of them are strictly letters (az or AZ). Retry (y/n)? "); break; } foreach (var item in getInvalidPathChars) if (fileNameSubStr.Remove(fileNameSubStr.LastIndexOf(".")).Contains(item.ToString())) { Console.Write("Invalid File Name: File name contains at least\n" + "one invalid character. Retry (y/n)? "); tf = false; break; } if (!tf) break; else Console.Write("'{0}' is a valid name.\nWould you like to enter a new file path (y/n)? ", directoryPathSubStr + fileNameSubStr); break; } directoryPathSubStr = fileNameSubStr = string.Empty; position = 0; do { yn = @Console.ReadLine(); switch (yn) { case ("y"): tf = true; break; case ("n"): { Console.WriteLine("Exiting application"); break; } default: { Console.Write("Only characters \"y\" or \"n\" allowed. Please, retry."); break; } } } while ((yn != "y") && (yn != "n")); } while (yn == "y"); Console.ReadLine(); } }
您可以尝试将Path.IsPathRooted()与Path.GetInvalidFileNameChars()结合使用,以确保path中途没问题。