In C# check that filename is *possibly* valid (not that it exists)
System.IO命名空间中是否有一个检查文件名有效性的方法?
例如,
或者有点棘手,
我想我自己可以编写这样的方法,但我对内置的方法更感兴趣。
做就是了;
1 2 3 4 5 6 7 8 9 10 11 12 | System.IO.FileInfo fi = null; try { fi = new System.IO.FileInfo(fileName); } catch (ArgumentException) { } catch (System.IO.PathTooLongException) { } catch (NotSupportedException) { } if (ReferenceEquals(fi, null)) { // file name is not valid } else { // file name is valid... May check for existence by calling fi.Exists. } |
要创建
您可以从Path.GetInvalidPathChars和GetInvalidFileNameChars中获取无效字符列表,如本问题中所述。
正如jberger所指出的,还有一些其他字符未包含在此方法的响应中。有关Windows平台的更多详细信息,请查看MSDN上的命名文件,路径和命名空间,
正如Micah指出的那样,有Directory.GetLogicalDrives来获取有效驱动器的列表。
您可以使用System.Uri类。 Uri类不仅对Web URL有用,它还处理文件系统路径。使用Uri.TryCreate方法查找路径是否为root,然后使用IsLoopback属性确定Uri是否引用本地计算机。
这是一个简单的方法,用于确定字符串是否为有效,本地和根文件路径。
1 2 3 4 5 | public bool IsPathValidRootedLocal(String pathString) { Uri pathUri; Boolean isValidUri = Uri.TryCreate(pathString, UriKind.Absolute, out pathUri); return isValidUri && pathUri != null && pathUri.IsLoopback; } |
我相信这会奏效。
您可以使用
1 2 3 | Directory.GetLogicalDrives() // Returns an array of strings like"c:" Path.GetInvalidFileNameChars() // Returns an array of characters that cannot be used in a file name Path.GetInvalidPathChars() // Returns an array of characters that cannot be used in a path. |
如建议您可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | bool IsValidFilename(string testName) { string regexString ="[" + Regex.Escape(Path.GetInvalidPathChars()) +"]"; Regex containsABadCharacter = new Regex(regexString); if (containsABadCharacter.IsMatch(testName)) { return false; } // Check for drive string pathRoot = Path.GetPathRoot(testName); if (Directory.GetLogicalDrives().Contains(pathRoot)) { // etc } // other checks for UNC, drive-path format, etc return true; } |
即使文件名有效,您仍可能希望
如果你不会在短时间内用数百个文件颠倒磁盘,我认为创建一个空文件是一种合理的方法。
如果你真的想要更轻松的东西,比如检查无效的字符,那么将你的文件名与Path.GetInvalidFileNameChars()进行比较。
以为我会发布一个解决方案,我在寻找相同问题的稳健解决方案之后,从我找到的一些答案拼凑而成。希望它可以帮助别人。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using System.IO; //.. public static bool ValidateFilePath(string path, bool RequireDirectory, bool IncludeFileName, bool RequireFileName = false) { if (string.IsNullOrEmpty(path)) { return false; } string root = null; string directory = null; string filename = null; try { // throw ArgumentException - The path parameter contains invalid characters, is empty, or contains only white spaces. root = Path.GetPathRoot(path); // throw ArgumentException - path contains one or more of the invalid characters defined in GetInvalidPathChars. // -or- String.Empty was passed to path. directory = Path.GetDirectoryName(path); // path contains one or more of the invalid characters defined in GetInvalidPathChars if (IncludeFileName) { filename = Path.GetFileName(path); } } catch (ArgumentException) { return false; } // null if path is null, or an empty string if path does not contain root directory information if (String.IsNullOrEmpty(root)) { return false; } // null if path denotes a root directory or is null. Returns String.Empty if path does not contain directory information if (String.IsNullOrEmpty(directory)) { return false; } if (RequireFileName) { // if the last character of path is a directory or volume separator character, this method returns String.Empty if (String.IsNullOrEmpty(filename)) { return false; } // check for illegal chars in filename if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) { return false; } } return true; } |
尝试这种方法,试图涵盖所有可能的异常情况。它适用于几乎所有与Windows相关的路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | /// <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; } |
如果路径或文件名无效,则有几个System.IO.Path方法将抛出异常:
- Path.IsPathRooted()
- Path.GetFileName()
http://msdn.microsoft.com/en-us/library/system.io.path_methods.aspx
在
要在路径中执行此操作,请在同一个类上调用静态
要确定路径的根是否有效,可以在
我有幸使用正则表达式,正如其他人所表明的那样。
要记住的一件事是Windows至少禁止某些文件名,否则这些文件名包含法律字符。一些想到:com,nul,prn。
我现在没有它,但我有一个正则表达式考虑这些文件名。如果你想我可以发布它,否则我相信你可以像我一样找到它:谷歌。
-Jay
我不知道开箱即用的任何东西可以为你验证所有这些,但
首先,它有:
1 | char[] invalidChars = Path.GetInvalidFileNameChars(); //returns invalid charachters |
要么:
1 | Path.GetPathRoot(string); // will return the root. |
认为现在回答为时已晚,但......
如果是带有卷名的路径,你可以写这样的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; using System.Linq; using System.IO; // ... var drives = Environment.GetLogicalDrives(); var invalidChars = Regex.Replace(new string(Path.GetInvalidFileNameChars()),"[\\\\/]",""); var drive = drives.FirstOrDefault(d => filePath.StartsWith(d)); if (drive != null) { var fileDirPath = filePath.Substring(drive.Length); if (0 < fileDirPath.Length) { if (fileDirPath.IndexOfAny(invalidChars.ToCharArray()) == -1) { if (Path.Combine(drive, fileDirPath) != drive) { // path correct and we can proceed } } } } |
这将为您提供机器上的驱动器:
1 | System.IO.DriveInfo.GetDrives() |
这两种方法会让你检查不好的字符:
1 2 | System.IO.Path.GetInvalidFileNameChars(); System.IO.Path.GetInvalidPathChars(); |
可能最麻烦的方法是构建一个自定义方法,混合使用正则表达式和小文件系统的组合(例如,查看驱动器)