В С# проверьте, что имя файла * возможно * действительное (не то, что оно существует)
Есть ли метод в пространстве имен System.IO, который проверяет правильность имени файла?
Например, C:\foo\bar
будет проверять, а :"~-*
не будет
Или немного сложнее, X:\foo\bar
будет проверять наличие в системе диска X:
, но в противном случае это не будет.
Я полагаю, что сам мог написать такой метод, но меня больше интересует встроенный.
Ответы
Ответ 1
Просто сделай;
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
файл не требуется.
Ответ 2
Вы можете получить список недопустимых символов из Path.GetInvalidPathChars и GetInvalidFileNameChars, как обсуждалось в этом вопросе.
Как отмечено jberger, есть некоторые другие символы, которые не включены в ответ от этого метода. Для получения более подробной информации о платформе Windows ознакомьтесь с Именование файлов, путей и пространств имен на MSDN,
Как указывает Micah , есть Directory.GetLogicalDrives, чтобы получить список допустимых дисков.
Ответ 3
Существует несколько методов, которые можно использовать в пространстве имен 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;
}
Ответ 4
Вы можете использовать класс System.Uri. Класс Uri не только полезен для веб-адресов, но также обрабатывает пути файловой системы. Используйте метод Uri.TryCreate, чтобы определить, запущен ли путь, а затем использовать свойство IsLoopback, чтобы определить, ссылается ли Uri на локальную машину.
Вот простой метод, который определяет, является ли строка допустимым, локальным и корневым пути к файлу.
public bool IsPathValidRootedLocal(String pathString) {
Uri pathUri;
Boolean isValidUri = Uri.TryCreate(pathString, UriKind.Absolute, out pathUri);
return isValidUri && pathUri != null && pathUri.IsLoopback;
}
Я уверен, что это сработает.
Ответ 5
Даже если имя файла является допустимым, вы все равно можете touch
убедиться, что у пользователя есть разрешение на запись.
Если вы не будете избивать диск сотнями файлов за короткий промежуток времени, я думаю, что создание пустого файла - разумный подход.
Если вы действительно хотите что-то более легкое, например, просто проверяете недопустимые символы, сравните свое имя файла с Path.GetInvalidFileNameChars().
Ответ 6
Некоторые из методов System.IO.Path будут генерировать исключения, если путь или имя файла недопустимы:
- Path.IsPathRooted()
- Path.GetFileName()
http://msdn.microsoft.com/en-us/library/system.io.path_methods.aspx
Ответ 7
Думаю, что я опубликую решение, которое я собрал из бит ответов, которые я нашел после поиска надежного решения той же проблемы. Надеюсь, это поможет кому-то другому.
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)
{
//f 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;
}
Ответ 8
Используйте статический GetInvalidFileNameChars
метод на Path
class в System.IO
namespace, чтобы определить, какие символы являются незаконными в имени файла.
Чтобы сделать это в пути, вызовите статический метод GetInvalidPathChars
в том же классе.
Чтобы определить, является ли корень пути действительным, вы вызываете статический метод GetPathRoot
в классе Path
для получить корень, а затем использовать Directory
класс, чтобы определить, действительно ли он. Затем вы можете проверить остальную часть пути как обычно.
Ответ 9
Я ничего не знаю из коробки, которая может просто подтвердить все это для вас, однако класс Path
в .NET
может помочь вам в огромной степени.
Для начала он имеет:
char[] invalidChars = Path.GetInvalidFileNameChars(); //returns invalid charachters
или
Path.GetPathRoot(string); // will return the root.
Ответ 10
Это даст вам диски на машине:
System.IO.DriveInfo.GetDrives()
Эти два метода приведут к ошибкам для проверки:
System.IO.Path.GetInvalidFileNameChars();
System.IO.Path.GetInvalidPathChars();
Ответ 11
Мне повезло с использованием регулярных выражений, как показали другие.
Следует иметь в виду, что Windows по крайней мере запрещает некоторые имена файлов, которые иначе содержат нелегальные символы. Некоторые приходят на ум: com, nul, prn.
Теперь у меня его нет, но у меня есть регулярное выражение, которое учитывает это имя файла. Если вы хотите, я могу опубликовать его, иначе я уверен, что вы можете найти его так же, как я: Google.
-Jay
Ответ 12
Попробуйте этот метод, который попытается охватить все возможные сценарии исключений. Он будет работать практически для всех связанных с 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;
}
Ответ 13
Вероятно, путь bast заключается в создании настраиваемого метода, смешивающего сочетание регулярных выражений и небольшого поиска в вашей файловой системе (например, для просмотра дисков).
Ответ 14
Подумайте, слишком поздно, чтобы ответить, но...:)
в случае пути с именем тома вы можете написать что-то вроде этого:
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
}
}
}
}