titledborder setborder java file

setborder - Java: ¿cómo saber si un nombre de archivo es válido?



setborder java (8)

Así es como lo implementé:

public boolean isValidFileName(final String aFileName) { final File aFile = new File(aFileName); boolean isValid = true; try { if (aFile.createNewFile()) { aFile.delete(); } } catch (IOException e) { isValid = false; } return isValid; }

En mi aplicación Java estoy cambiando el nombre de los archivos a un nombre de archivo provisto en un parámetro String. Hay un método

boolean OKtoRename(String oldName, String newName)

que básicamente verifica si el nuevo Nombre ya no está ocupado por otro archivo, ya que no quisiera enterrar los existentes.

Ahora se me ocurrió que tal vez newName String no denotará un nombre de archivo válido. Así que pensé en agregar esta verificación al método:

if (new File(newName).isFile()) { return false; }

Lo cual obviamente no es la forma correcta de hacerlo, ya que en la mayoría de los casos el archivo nuevo aún no existe y, por lo tanto, aunque es correcto para Renombrar, la función devuelve falso.

Me preguntaba, ¿hay algún método (sé que no hay para los objetos java.io.File) como canExist() ? ¿O tendré que recurrir a regex para asegurarme de que newFile String no contenga caracteres no válidos (por ejemplo,?, *, ", :)? Me pregunto si tal vez haya una función escondida en alguna parte del JDK que me diga si una cadena posiblemente podría denotar un nombre de archivo válido.


Para mí, parece ser un problema dependiente del sistema operativo. Es posible que simplemente desee comprobar si hay algún carácter no válido en el nombre del archivo. Windows hace esto cuando intenta cambiar el nombre del archivo, aparece un mensaje que dice que un archivo no puede contener ninguno de los siguientes caracteres: / /: *? <> | No estoy seguro si su pregunta es "¿hay una biblioteca haciendo el trabajo por mí?" en ese caso, no conozco ninguno.


Recopilé una lista de caracteres de nombre de archivo ilegal (considerando los sistemas UNIX, Mac OS X y Windows) basados ​​en algunas investigaciones en línea hace un par de meses. Si el nuevo nombre de archivo contiene alguno de estos, existe el riesgo de que no sea válido en todas las plataformas.

private static final char[] ILLEGAL_CHARACTERS = { ''/'', ''/n'', ''/r'', ''/t'', ''/0'', ''/f'', ''`'', ''?'', ''*'', ''//', ''<'', ''>'', ''|'', ''/"'', '':'' };

EDITAR: Me gustaría hacer hincapié en que esta no es una solución completa : como señaló un comentarista, aunque pase esta prueba, su nombre de archivo podría ser una palabra clave específica de Windows como COM, PRN, etc. Sin embargo, si su archivo nombre contiene cualquiera de estos caracteres, sin duda causará problemas en un entorno multiplataforma.


Si desarrolla para Eclipse, consulte org.eclipse.core.internal.resources.OS

public abstract class OS { private static final String INSTALLED_PLATFORM; public static final char[] INVALID_RESOURCE_CHARACTERS; private static final String[] INVALID_RESOURCE_BASENAMES; private static final String[] INVALID_RESOURCE_FULLNAMES; static { //find out the OS being used //setup the invalid names INSTALLED_PLATFORM = Platform.getOS(); if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) { //valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp INVALID_RESOURCE_CHARACTERS = new char[] {''//', ''/'', '':'', ''*'', ''?'', ''"'', ''<'', ''>'', ''|''}; INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ Arrays.sort(INVALID_RESOURCE_BASENAMES); //CLOCK$ may be used if an extension is provided INVALID_RESOURCE_FULLNAMES = new String[] {"clock$"}; //$NON-NLS-1$ } else { //only front slash and null char are invalid on UNIXes //taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html INVALID_RESOURCE_CHARACTERS = new char[] {''/'', ''/0'',}; INVALID_RESOURCE_BASENAMES = null; INVALID_RESOURCE_FULLNAMES = null; } } /** * Returns true if the given name is a valid resource name on this operating system, * and false otherwise. */ public static boolean isNameValid(String name) { //. and .. have special meaning on all platforms if (name.equals(".") || name.equals("..")) //$NON-NLS-1$ //$NON-NLS-2$ return false; if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) { //empty names are not valid final int length = name.length(); if (length == 0) return false; final char lastChar = name.charAt(length-1); // filenames ending in dot are not valid if (lastChar == ''.'') return false; // file names ending with whitespace are truncated (bug 118997) if (Character.isWhitespace(lastChar)) return false; int dot = name.indexOf(''.''); //on windows, filename suffixes are not relevant to name validity String basename = dot == -1 ? name : name.substring(0, dot); if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0) return false; return Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) < 0; } return true; } }


Solo algo que encontré, en java 7 y posteriores, hay una clase llamada Paths que tiene un método llamado get que toma una o más String y tiros

InvalidPathException : si la cadena de ruta de acceso no se puede convertir a una ruta


Use createNewFile() , que creará atómicamente el archivo solo si aún no existe.

Si se crea el archivo, el nombre es válido y no está arruinando un archivo existente. A continuación, puede abrir los archivos y copiar datos de manera eficiente de uno a otro con FileChannel.transferXXX operaciones FileChannel.transferXXX .

Una cosa importante a tener en cuenta es que, en general, el cheque y la creación deben ser atómicos. Si primero verifica si una operación es segura y luego realiza la operación como un paso separado, las condiciones pueden haber cambiado mientras tanto, haciendo que la operación no sea segura.

En esta publicación relacionada se encuentra disponible material de reflexión: "Mover / copiar operaciones en Java".

Actualizar:

Desde esta respuesta, se han introducido las API de NIO.2, que agregan más interacción con el sistema de archivos.

Supongamos que tiene un programa interactivo y desea validar después de cada pulsación de tecla si el archivo es potencialmente válido. Por ejemplo, es posible que desee habilitar un botón "Guardar" solo cuando la entrada sea válida en lugar de abrir un cuadro de diálogo de error luego de presionar "Guardar". Crear y asegurar la eliminación de muchos archivos innecesarios que mi sugerencia anterior requeriría parece un desastre.

Con NIO.2, no puede crear una instancia de Path contenga caracteres que sean ilegales para el sistema de archivos. Una InvalidPathException se InvalidPathException tan pronto como intente crear la Path .

Sin embargo, no hay una API para validar nombres ilegales compuestos de caracteres válidos, como "PRN" en Windows. Como solución alternativa, la experimentación demostró que el uso de un nombre de archivo ilegal generaría una excepción distintiva al intentar acceder a los atributos (utilizando Files.getLastModifiedTime() , por ejemplo).

Si especifica un nombre legal para un archivo que existe, no obtiene ninguna excepción.

Si especifica un nombre legal para un archivo que no existe, genera NoSuchFileException .

Si especifica un nombre ilegal, se FileSystemException .

Sin embargo, esto parece muy complicado y podría no ser confiable en otros sistemas operativos.


Utilizando

String validName = URLEncoder.encode( fileName , "UTF-8"); File newFile = new File( validName );

El trabajo

Acabo de encontrar hoy. No estoy seguro de si funciona el 100% del tiempo, pero hasta ahora, he podido crear nombres de archivo válidos.


Here se sugiere una forma específica del sistema.

public static boolean isFilenameValid(String file) { File f = new File(file); try { f.getCanonicalPath(); return true; } catch (IOException e) { return false; } }