En C #, compruebe que el nombre de archivo sea * posiblemente * válido (no que exista)

¿Hay algún método en el espacio de nombres System.IO que verifique la validez de un nombre de archivo?

Por ejemplo, C:\foo\bar validaría y :"~-* no

O un poco más complicado, X:\foo\bar validaría si hay una unidad X: en el sistema, pero no lo haría de otra manera.

Supongo que podría escribir ese método yo mismo, pero estoy más interesado en uno integrado.

Solo haz;

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

Para crear una instancia de FileInfo , el archivo no necesita existir.

Puede obtener una lista de caracteres no válidos de Path.GetInvalidPathChars y GetInvalidFileNameChars como se explica en esta pregunta.

Como señaló jberger, hay algunos otros caracteres que no están incluidos en la respuesta de este método. Para obtener más información sobre la plataforma de Windows, consulte Nombres de archivos, rutas y espacios de nombres en MSDN,

Como señala Micah, hay Directory.GetLogicalDrives para obtener una lista de unidades válidas.

Puede hacer uso de la clase System.Uri. La clase Uri no solo es útil para las URL web, sino que también maneja las rutas del sistema de archivos. Use el método Uri.TryCreate para encontrar si la ruta está enraizada y luego use la propiedad IsLoopback para determinar si el Uri hace referencia a la máquina local.

Aquí hay un método simple que determina si una cadena es una ruta de archivo válida, local y rooteada.

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

Estoy seguro de que esto funcionará.

Hay varios métodos que puede usar que existen en el espacio de nombres 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. 

Como se sugiere, usted puede hacer esto:

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

Incluso si el nombre del archivo es válido, es posible que desee touch para asegurarse de que el usuario tenga permiso para escribir.

Si no va a demoler el disco con cientos de archivos en un corto período de tiempo, creo que crear un archivo vacío es un enfoque razonable.

Si realmente quieres algo más liviano, como solo buscar caracteres no válidos, entonces compara tu nombre de archivo con Path.GetInvalidFileNameChars ().

Pensé que publicaría una solución que improvisé a partir de las respuestas que encontré después de buscar una solución robusta para el mismo problema. Espero que ayude a alguien más.

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

Varios de los métodos System.IO.Path arrojarán excepciones si la ruta o el nombre de archivo no son válidos:

  • Path.IsPathRooted ()
  • Path.GetFileName ()

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

Use el método estático GetInvalidFileNameChars en la clase Path en el espacio de nombres System.IO para determinar qué caracteres son ilegales en un nombre de archivo.

Para hacerlo en una ruta, llame al método estático GetInvalidPathChars en la misma clase.

Para determinar si la raíz de una ruta es válida, debe llamar al método GetPathRoot estático en la clase Path para obtener la raíz y luego usar la clase Directory para determinar si es válida. Entonces puedes validar el rest de la ruta normalmente.

Esto te proporcionará las unidades en la máquina:

 System.IO.DriveInfo.GetDrives() 

Estos dos métodos le darán los malos caracteres para verificar:

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

He tenido suerte usando expresiones regulares como otros han demostrado.

Una cosa a tener en cuenta es que Windows al menos prohíbe algunos nombres de archivos que de otra manera contienen caracteres legales. Algunos vienen a la mente: com, nul, prn.

No lo tengo conmigo ahora, pero tengo una expresión regular que toma en consideración estos nombres de archivo. Si quieres puedo publicarlo, de lo contrario estoy seguro de que puedes encontrarlo de la misma manera que lo hice: Google.

-Arrendajo

No sé nada de nada que pueda validar todo eso por ti, sin embargo, la clase Path en .NET puede ayudarte muchísimo.

Para empezar, tiene:

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

o:

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

Pruebe este método que trataría de cubrir todos los posibles escenarios de Excepciones. Funcionaría para casi todas las rutas relacionadas con Windows.

 ///  /// Validate the Path. If path is relative append the path to the project directory by default. ///  /// Path to validate /// Relative path /// If want to check for File Path ///  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; } 

Probablemente la forma de bast es construir un método personalizado que mezcle una combinación de expresiones regulares y pequeñas búsquedas en su sistema de archivos (para ver las unidades, por ejemplo)

Creo que es demasiado tarde para responder, pero … 🙂 en caso de ruta con el nombre del volumen podría escribir algo como esto:

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