(edición de aclaración y adición de un código)¿Cómo puedo abrir archivos que contienen acentos en Java?
Hola, Tenemos un requisito para analizar los datos enviados por los usuarios en todo el mundo. Nuestros sistemas Linux tienen una configuración regional predeterminada en_US.UTF-8. Sin embargo, a menudo recibimos archivos con marcas diacríticas en sus nombres como "special_á_ã_è_characters.doc
". Aunque el sistema operativo puede tratar bien estos archivos, y una cadena muestra que el sistema operativo transfiere el nombre de archivo correcto al programa Java, Java ordena los nombres y lanza una excepción de "archivo no encontrado" para tratar de abrirlos.
Este sencillo programa puede ilustrar el tema:
import java.io.*;
import java.text.*;
public class load_i18n
{
public static void main(String [] args) {
File actual = new File(".");
for(File f : actual.listFiles()){
System.out.println(f.getName());
}
}
}
La ejecución de este programa en un directorio que contiene el archivo special_á_ã_è_characters.doc
y el valor predeterminado de EE.UU. Inglés locale da:
special_�_�_�_characters.doc
Configuración del idioma a través de la exportación LANG = es_ES @ UTF-8 imprime el nombre de archivo correctamente (pero es una solución inaceptable ya que todo el sistema se está ejecutando en español). Establecer explícitamente la configuración regional el programa como el siguiente tampoco tiene ningún efecto. A continuación he modificado el programa para a) intente abrir el archivo y b) imprimir el nombre en ASCII y como una matriz de bytes cuando no puede abrir el archivo:
import java.io.*;
import java.util.Locale;
import java.text.*;
public class load_i18n
{
public static void main(String [] args) {
// Stream to read file
FileInputStream fin;
Locale locale = new Locale("es", "ES");
Locale.setDefault(locale);
File actual = new File(".");
System.out.println(Locale.getDefault());
for(File f : actual.listFiles()){
try {
fin = new FileInputStream (f.getName());
}
catch (IOException e){
System.err.println ("Can't open the file " + f.getName() + ". Printing as byte array.");
byte[] textArray = f.getName().getBytes();
for(byte b: textArray){
System.err.print(b + " ");
}
System.err.println();
System.exit(-1);
}
System.out.println(f.getName());
}
}
}
Esto produce la salida
es_ES
load_i18n.class
Can't open the file special_�_�_�_characters.doc. Printing as byte array.
115 112 101 99 105 97 108 95 -17 -65 -67 95 -17 -65 -67 95 -17 -65 -67 95 99 104 97 114 97 99 116 101 114 115 46 100 111 99
Esto muestra que el problema NO es solo un problema con la visualización de la consola, ya que los mismos caracteres y sus representaciones se envían en bytes o en formato ASCII. De hecho, pantalla de la consola funciona incluso cuando se utiliza LANG = en_US.UTF-8 para algunas utilidades como eco de fiesta:
[[email protected] tmp]$ echo $LANG
en_US.UTF-8
[[email protected] tmp]$ echo *
load_i18n.class special_á_ã_è_characters.doc
[[email protected] tmp]$ ls
load_i18n.class special_?_?_?_characters.doc
[[email protected] tmp]$
¿Es posible modificar este código de tal manera que cuando se ejecuta en Linux con LANG = en_US.UTF-8, lee el nombre del archivo de tal manera que se puede abrir con éxito?
Su ejemplo no muestra que intente abrir esos archivos, solo imprima el nombre.Si Java puede abrir el archivo y si su consola de salida estándar (que no tiene nada que ver con Java) puede representar correctamente los caracteres, son dos cosas muy diferentes. Muéstranos el código que dio la IOException y da los detalles de IOException y stacktrace. –
Echa un vistazo a las respuestas que recomiendan el uso de las propiedades del sistema Java (user.language, user.country, user.variant) aquí: http://stackoverflow.com/questions/64038/setting-java-locale-settings –
Lo siento - I nunca llegar al punto de abrir el archivo. Una llamada a, digamos FileInputStream fallaría porque no puedo pasarle el nombre correcto del archivo. El archivo "special_�_�_�_characters.doc" no existe. El archivo "special_á_ã_è_characters.doc" sí lo hace, pero mi iteración de directorios nunca lo menciona. –