txt - ¿Hay alguna forma en Java para determinar si una ruta es válida sin intentar crear un archivo?
modificar archivos txt en java (5)
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, por lo que Hay una forma de determinar si el String que tengo es una ruta de archivo válida sin intentar crear el 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 posible enfoque puede intentar 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 ...
La clase de ruta introducida en Java 7 agrega nuevas alternativas, como las siguientes:
(No funciona correctamente en Linux - siempre devuelve verdadero)
/**
* <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;
}
Varias cosas pueden salir mal cuando intentas 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 al punto, esos pueden cambiar entre cuando intentas consultar para ver si puedes y cuándo puedes hacerlo. 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
tiene 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.
File.getCanonicalPath()
es bastante útil para este propósito. Se lanzan excepciones de IO para ciertos tipos de nombres de archivo no válidos (por ejemplo, CON
, PRN
, *?*
En Windows) cuando se resuelven en contra del SO o el sistema de archivos. Sin embargo, esto solo sirve como un control preliminar; aún necesitará manejar otras fallas al crear el archivo (por ejemplo, permisos insuficientes, falta de espacio en disco, restricciones de seguridad).
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 proporciona una indicación clara de si tiene permisos para escribir en el directorio.
boolean canWrite(File file) {
if (file.exists()) {
return file.canWrite();
}
else {
try {
file.createNewFile();
file.delete();
return true;
}
catch (Exception e) {
return false;
}
}
}