2010-06-18 32 views
36

Me gustaría saber cómo determinar si la cadena es una ruta de archivo válida.Determinar a través de C# si una cadena es una ruta de archivo válida

La ruta del archivo puede o puede no existir.

+1

¿Quiere decir que usted tiene una cadena que se parece a un camino, y si existe o no el archivo, desea saber si un archivo en el "camino" dada podría existir? Si la ruta es válida, incluso si no hay ningún archivo en esa ubicación? – SqlRyan

+0

posible duplicado de [¿Cómo comprobar si la cadena dada es legal (permitido) nombre de archivo en Windows?] (Http://stackoverflow.com/questions/62771/how-check-if-given-string-is-legal-allowed- nombre-de-archivo-bajo-ventanas) – nawfal

+0

Si su preocupación es más generalmente probar si una cadena puede representar un archivo *** o *** una carpeta, vea [esta respuesta] (http://stackoverflow.com/a/3137165/1497596) o [esta respuesta relacionada] (http://stackoverflow.com/a/41049011/1497596). – DavidRR

Respuesta

18

Una comprobación precisa el 100% de formato de cadena de un camino es bastante difícil, ya que dependerá del sistema de archivos en el que se utiliza (y protocolos de red si no está en el mismo equipo)

Incluso dentro de Windows o incluso NTFS no es simple, ya que todavía depende de la API que .NET está utilizando en el fondo para comunicarse con el kernel.

Y puesto que la mayoría de los sistemas de archivos Unicode apoyo hoy en día, también se podría necesitar para comprobar si todas las reglas para Unicode correcly codificada, la normalización, etc, etc

lo que he hecho es hacer sólo algunos controles básicos, y luego maneje las excepciones correctamente una vez que se utiliza la ruta. Para ver posibles reglas:

+0

su wikipedia;) – atamanroman

+1

:-) gracias campo, lo arregló. – Stefan

44

Puede usar el constructor FileInfo. Lanzará una ArgumentException si "El nombre del archivo está vacío, contiene solo espacios en blanco o contiene caracteres no válidos". También puede lanzar SecurityException o UnauthorizedAccessException, que creo que puedes ignorar si solo te preocupa el formato.

Otra opción es verificar directamente contra Path.GetInvalidPathChars. Por ejemplo:

boolean possiblePath = pathString.IndexOfAny(Path.GetInvalidPathChars()) == -1; 
+3

FWIW, esto arrojará falsos positivos. También deberá verificar los permisos y que la carpeta/nombre de archivo no es una de las ilegales (http://en.wikipedia.org/wiki/DOS#Reserved_device_names). –

+0

'new FileInfo (" test ")' es perfectamente válido, pero no es un archivo. – Julien

+1

@Julien Si no pasa una ruta completa, la tratará como una ruta relativa de lo que devuelve 'Directory.GetCurrentDirectory()'. Entonces, si estás trabajando en 'C: \ Temp' y llamas' new FileInfo ("test"); ', la propiedad' FullName' será 'C: \ Temp \ test'. – tehDorf

2

¿Has probado las expresiones regulares?

^([a-zA-Z]\:)(\\[^\\/:*?<>"|]*(?<![ ]))*(\.[a-zA-Z]{2,6})$ 

deben trabajar

+1

Nunca dijo la ruta absoluta, no hay límite para la longitud de la extensión del archivo, y eso no es portátil. –

+39

Algunas personas, cuando se enfrentan con un problema, piensan "Lo sé, usaré expresiones regulares". Ahora ellos tienen dos problemas. -Jamie Zawinski – womp

0

He encontrado esto en regexlib.com (http://regexlib.com/REDetails.aspx?regexp_id=345) por Dmitry Borysov .

"Nombre de archivo de validación valida tanto UNC (\ server \ share \ file), y la ruta de MS regular. (Archivo c: \)"

^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?))\\)*[^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?$ 

hace funcionar con un Regex.IsMatch y obtendrá un bool que indica si es válido o no. Creo que las expresiones regulares son el camino a seguir, ya que el archivo puede no existir.

0

La clase estática System.IO.Path puede hacer lo que está pidiendo.

8

Aquí están algunas cosas que usted puede utilizar:

  • para comprobar si la unidad es correcto (por ejemplo en un ordenador de la unidad X: \ existe, pero no en el suyo): utilizar Path.IsPathRooted para ver si se trata de no es una ruta relativa y luego usa las unidades desde Environment.GetLogicalDrives() para ver si tu ruta contiene una de las unidades válidas.
  • Para comprobar si hay caracteres válidos, tiene dos métodos: Path.GetInvalidFileNameChars() y Path.GetInvalidPathChars() que no se superponen por completo.También puede utilizar Path.GetDirectoryName(path) y Path.GetFileName(fileName) con su nombre de entrada, lo que throw an exception si el parámetro

La ruta contiene caracteres no válidos, está vacío o contiene sólo espacios en blanco.

3

No puede estar seguro hasta que intente crear ese archivo. Tal vez la ruta sea válida, pero la configuración de seguridad no permitirá la creación del archivo. La única instancia que podría decirle si la ruta es REALMENTE válida sería el sistema operativo, entonces, ¿por qué no intenta crear ese archivo y capturar la excepción IOException que indica que algo salió mal? Este es el enfoque más fácil: asumir que la entrada es válida y hacer algo si no es así, en lugar de hacer mucho trabajo innecesario.

0

Usted puede simplemente utilizar Path.Combine() dentro de una sentencia intento de captura:

string path = @" your path "; 
try 
{ 
    Path.Combine(path); 
} 
catch 
{ 
    MessageBox.Show("Invalid path"); 
} 

Editar: Tenga en cuenta que esta función no lanza una excepción si la ruta contiene caracteres comodín ('*' y '?') ya que pueden usarse en cadenas de búsqueda.

+0

Esto realmente no capta cuando mi ruta es "algo ilegal" – MichaelvdNet

1

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.

/// <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; 
} 
1
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; 
     } 
     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 directoryInfo = new DirectoryInfo(Path.GetFullPath(path)); 
     try 
     { 
     if (!directoryInfo.Exists) 
     { 
      directoryInfo.Create(); 
     } 
     } 
     catch (Exception ex) 
     { 
     if (Log.IsErrorEnabled) 
     { 
      Log.Error(ex.Message); 
     } 
     return false; 
     }`enter code here` 

     return true; 
    } 
+0

Esto funciona para mí ... incluso la ubicación no existe en PC –

Cuestiones relacionadas