2009-01-22 20 views
49

Necesito determinar si un String proporcionado por el usuario es una ruta de archivo válida (es decir, si createNewFile() tendrá éxito o arrojará una excepción) pero no quiero inflar el sistema de archivos con archivos inútiles creados solo con fines de validación, Entonces, ¿hay alguna manera de determinar si el String que tengo es una ruta de archivo válida sin intentar crear el archivo?¿Hay alguna manera en Java para determinar si una ruta es válida sin intentar crear un archivo?

Sé que la definición de "ruta de archivo válida" varía según el sistema operativo, pero me preguntaba si hubo alguna forma rápida de aceptar "C:/foo" o "/ foo" y rechazar "banana" ... .un enfoque posible puede estar intentando crear el archivo y eventualmente eliminarlo si la creación tuvo éxito, pero espero que haya una forma más elegante de lograr el mismo resultado ...

+2

¿Puede alguien decirme cómo la pregunta anterior está EXACTAMENTE relacionada con esta: http://stackoverflow.com/questions/13924808/check-if-a-path-is-valid-or-legal-in-java? Bien, puedo dar 2 similitudes, ambas están escritas en inglés y usan la palabra "es". ¿Algo más que eso? –

+0

documentación del corrector relacionado de klocwork: [SV.PATH] (https://developer.klocwork.com/documentation/en/insight/10-1/sv-path): contiene pautas útiles – boly38

Respuesta

25

Esto verificaría la existencia del directorio también.

File file = new File("c:\\cygwin\\cygwin.bat"); 
if (!file.isDirectory()) 
    file = file.getParentFile(); 
if (file.exists()){ 
    ... 
} 

Parece que file.canWrite() no le da una clara indicación de si tiene permisos para escribir en el directorio.

+4

Uhm ... no lo hago Quiero comprobar si el archivo existe, quiero verificar si el archivo se puede crear en el sistema de archivos actual – Raibaz

+0

El problema es que la capacidad de crear el archivo podría cambiar después de que hayas revisado para ver si se puede crear – tddmonkey

+1

El código de krosenvold hace lo siguiente: ¿Ya existe el nombre de archivo pasado como un directorio, y si no, ¿existe el directorio en el que estaría? Esto tiene sentido ya que si el directorio está allí puede crear el archivo (permisos permitidos) Tenga en cuenta que el nuevo archivo ("foo") no crea un archivo. – mtruesdell

14

Un número de cosas pueden ir mal cuando intenta y crear un archivo:

  • Su falta de los permisos necesarios;
  • No hay suficiente espacio en el dispositivo;
  • El dispositivo experimenta un error;
  • Algunas políticas de seguridad personalizada le prohíben crear un archivo de un tipo particular;
  • etc.

Más concretamente, los que pueden cambiar entre el momento en que tratar de consulta para ver si se puede y cuando realmente se puede. En un entorno multiproceso, esta es una de las principales causas de las condiciones de carrera y puede ser una vulnerabilidad real de algunos programas.

Básicamente, solo tienes que intentar crearlo y ver si funciona. Y esa es la forma correcta de hacerlo. Es por eso que cosas como ConcurrentHashMap tienen un putIfAbsent() por lo que el control e inserción es una operación atómica y no sufre de condiciones de carrera. Exactamente el mismo principio está en juego aquí.

Si esto es solo parte de algún proceso de diagnóstico o de instalación, simplemente hágalo y vea si funciona. Una vez más, no hay garantía de que funcione más tarde.

Básicamente, su programa tiene que ser lo suficientemente robusto como para morir elegantemente si no puede escribir un archivo relevante.

+2

DON "T DIE" (en algunos casos), permite al usuario elegir otro volumen o medio. Tengo un IDE que muere cuando no puede escribir su archivo de proyecto. Bueno, el volumen está fuera de línea, permítame seleccionar otro lugar y continuar. – jim

14

File.getCanonicalPath() es bastante útil para este propósito. Se lanzan excepciones de IO para ciertos tipos de nombres de archivos no válidos (por ejemplo, CON, PRN, *?* en Windows) al resolver contra el sistema operativo o el sistema de archivos. Sin embargo, esto solo sirve como un control preliminar; aún necesitará manejar otras fallas cuando realmente cree el archivo (por ejemplo, permisos insuficientes, falta de espacio en el disco, restricciones de seguridad).

-1
boolean canWrite(File file) { 
    if (file.exists()) { 
    return file.canWrite(); 
    } 
    else { 
    try { 
     file.createNewFile(); 
     file.delete(); 
     return true; 
    } 
    catch (Exception e) { 
     return false; 
    } 
    } 
} 
+4

Esto no funciona del todo ya que 'File.canWrite()' no es confiable en Windows. Consulte [esta publicación] (http://www.thekua.com/atwork/2008/09/javaiofile-setreadonly-and -canwrite-broken-on-windows /) y el primer comentario de Peter Tseng para una solución alternativa –

20

clase Path introducido en Java 7 añade nuevas alternativas, como la siguiente:
(no no trabajo correctamente bajo Linux - siempre devuelve true)

 /** 
     * <pre> 
     * Checks if a string is a valid path. 
     * Null safe. 
     * 
     * Calling examples: 
     * isValidPath("c:/test");  //returns true 
     * isValidPath("c:/te:t");  //returns false 
     * isValidPath("c:/te?t");  //returns false 
     * isValidPath("c/te*t");  //returns false 
     * isValidPath("good.txt");  //returns true 
     * isValidPath("not|good.txt"); //returns false 
     * isValidPath("not:good.txt"); //returns false 
     * </pre> 
     */ 
     public static boolean isValidPath(String path) { 

      try { 

       Paths.get(path); 

      } catch (InvalidPathException | NullPointerException ex) { 
       return false; 
      } 

      return true; 
     } 
+0

¡Hermosa! Solución agradable y limpia sin la necesidad de incluir bibliotecas Apache –

+0

Gracias @ Tim Visée. Me alegra que encuentre una buena solución (0: – c0der

+0

tenga en cuenta que esto siempre devuelve 'true' en Linux. En mi propia prueba, incluso' Paths.get ("archivo \ u0000") 'no arroja' InvalidPathException'. – Groostav

Cuestiones relacionadas