在 C # 中检查文件名是否 * 可能 * 有效(并不是说它存在)

System.IO 名称空间中是否有检查文件名有效性的方法?

例如,C:\foo\bar会验证,而 :"~-*不会

或者更棘手一点,如果系统上有一个 X:驱动器,X:\foo\bar会验证,但是否则不会验证。

我想我可以自己编写这样的方法,但我更感兴趣的是内置的方法。

129796 次浏览

您可以从 Path.GetInvalidPathCharsGetInvalidFileNameChars获得无效字符列表,如 这个问题中所讨论的。

正如 jberger 所指出的,这个方法的响应中没有包含其他一些字符。有关 windows 平台的更多细节,请参见 MSDN 上的 命名文件、路径和命名空间

作为 Micah 指出,有 Directory.GetLogicalDrives来获得有效驱动器的列表。

照做就是了

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

为了创建 FileInfo实例,该文件不需要存在。

使用 System.IO名称空间Path上的静态 GetInvalidFileNameChars来确定文件名中哪些字符是非法的。

若要在路径中执行此操作,请在同一个类上调用静态 GetInvalidPathChars

要确定路径的根是否有效,可以调用 Path类上的静态 GetPathRoot来获取根,然后使用 Directory来确定它是否有效。然后您可以正常地验证路径的其余部分。

即使文件名是有效的,您可能仍然希望 touch它,以确保用户有权限写。

如果您不想在很短的时间内用数百个文件折腾磁盘,我认为创建一个空文件是一种合理的方法。

如果您真的想要一些更轻松的东西,比如只检查无效的字符,那么将您的文件名与 Path.GetInvalidFileNameChars ()进行比较。

最好的方法可能是构建一个自定义方法,将正则表达式和文件系统的小查找(例如查看驱动器)相结合

我不知道任何开箱即用的东西可以验证所有这些,但是 .NET中的 Path类可以极大地帮助你。

首先,它有:

char[] invalidChars = Path.GetInvalidFileNameChars(); //returns invalid charachters

或:

Path.GetPathRoot(string); // will return the root.

如果路径或文件名无效,几个 System.IO.Path 方法将引发异常:

  • Path.IsPathRooted ()
  • 路径

Http://msdn.microsoft.com/en-us/library/system.io.path_methods.aspx

System.IO命名空间中有几种方法可以使用:

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.

正如建议的那样,你可以这样做:

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

这样你就能拿到机器上的硬盘了:

System.IO.DriveInfo.GetDrives()

这两个方法会让你检查错误字符:

System.IO.Path.GetInvalidFileNameChars();
System.IO.Path.GetInvalidPathChars();

我很幸运地使用了正则表达式,就像其他人展示的那样。

需要记住的一点是,Windows 至少禁止一些包含合法字符的文件名。想到了几个: com,null,prn。

我现在没有带它,但是我有一个 regex,它将这些文件名考虑在内。如果你想,我可以发布它,否则我相信你可以找到它的方式和我一样: 谷歌。

你可以利用这个系统。Uri 课。Uri 类不仅对 web URL 有用,它还处理文件系统路径。用 Uri。方法查找路径是否有根,然后使用 IsLoopback 属性确定 Uri 是否引用本地计算机。

下面是一个简单的方法,用于确定字符串是否是有效的、本地的和有根的文件路径。

public bool IsPathValidRootedLocal(String pathString) {
Uri pathUri;
Boolean isValidUri = Uri.TryCreate(pathString, UriKind.Absolute, out pathUri);
return isValidUri && pathUri != null && pathUri.IsLoopback;
}

我相信这会奏效的。

我想现在回答太晚了,但是... :) 在使用卷名称的情况下,您可以编写如下代码:

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

我想我可以发布一个解决方案,这个解决方案是我在为同一个问题寻找一个可靠的解决方案之后,从一些答案中拼凑出来的。希望能帮到别人。

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 相关的路径。

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