Intenté usar java.io.FileReader para leer algunos archivos de texto y convertirlos en una cadena, pero descubrí que el resultado está codificado incorrectamente y no es legible en absoluto.
Aquí está mi entorno:
Windows 2003, codificación del sistema operativo: CP1252
Java 5.0
Mis archivos están codificados en UTF-8 o CP1252, y algunos de ellos (archivos codificados en UTF-8) pueden contener caracteres chinos (no latinos).
Yo uso el siguiente código para hacer mi trabajo:
private static String readFileAsString(String filePath)
throws java.io.IOException{
StringBuffer fileData = new StringBuffer(1000);
FileReader reader = new FileReader(filePath);
//System.out.println(reader.getEncoding());
BufferedReader reader = new BufferedReader(reader);
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
return fileData.toString();
}
El código anterior no funciona. Descubrí que la codificación del FileReader es CP1252 incluso si el texto está codificado en UTF-8. Pero el JavaDoc de java.io.FileReader dice que:
Los constructores de esta clase asumen que la codificación de caracteres predeterminada y el tamaño de byte-buffer predeterminado son apropiados.
¿Significa esto que no estoy obligado a configurar la codificación de caracteres por mi cuenta si estoy usando FileReader? Pero obtuve datos codificados incorrectamente actualmente, ¿cuál es la forma correcta de lidiar con mi situación? Gracias.
Respuestas:
Sí, debe especificar la codificación del archivo que desea leer.
Sí, esto significa que debe conocer la codificación del archivo que desea leer.
No, no hay una forma general de adivinar la codificación de cualquier archivo de "texto plano".
Los constructores de un argumento
FileReader
siempre usan la codificación predeterminada de la plataforma, que generalmente es una mala idea .Desde Java 11
FileReader
también ha ganado constructores que aceptan una codificación:new FileReader(file, charset)
ynew FileReader(fileName, charset)
.En versiones anteriores de java, debe usar .
new InputStreamReader(
new FileInputStream(pathToFile)
, <encoding>)
fuente
InputStreamReader
es unajava.io
clase, ¿sería "UTF8"?StandardCharsets.UTF_8
no hay posibilidad de escribir mal allí ;-) Pero sí, si vas con una cuerda"UTF8"
sería correcto (aunque parece recordar que aceptará ambas cosas).Byte Order Mark
, junto con ... bueno ... ¡establecer el orden de bytes! :) Como tal, me parece extraño que FileReader de Java no pueda detectar automáticamente UTF-16 que tiene una BOM de ese tipo ... De hecho, una vez escribí unaUnicodeFileReader
que hace exactamente eso. Desafortunadamente fuente cerrada, pero Google tiene su UnicodeReader que es muy similar.FileReader
utiliza la codificación predeterminada de la plataforma Java, que depende de la configuración del sistema de la computadora en la que se está ejecutando y generalmente es la codificación más popular entre los usuarios de esa configuración regional.Si esta "mejor suposición" no es correcta, entonces debe especificar la codificación explícitamente. Lamentablemente,
FileReader
no permite esto (supervisión importante en la API). En su lugar, debe usarnew InputStreamReader(new FileInputStream(filePath), encoding)
e idealmente obtener la codificación de los metadatos sobre el archivo.fuente
FileReader
utiliza la codificación predeterminada de la plataforma Java, que depende de la configuración del sistema de la computadora en la que se está ejecutando y, en general, es la codificación más popular entre los usuarios de esa configuración regional". Yo no diría eso. Al menos de Windows. Por algunas extrañas razones técnicas / históricas, la JVM ignora el hecho de que Unicode es la codificación recomendada en Windows para 'todas las aplicaciones nuevas' y en su lugar siempre actúa como si la codificación heredada configurada como reserva para aplicaciones heredadas sea el 'valor predeterminado de la plataforma'.Desde Java 11 puede usar eso:
fuente
Para Java 7+ doc puede usar esto:
Aquí están todos los documentos de Charsets
Por ejemplo, si su archivo está en CP1252, use este método
Aquí hay otros nombres canónicos para codificaciones Java tanto para IO como para NIO doc.
Si usted no sabe con codificación es exactamente lo que tienes en un archivo, es posible utilizar algunas librerías de terceros, como esta herramienta de Google este , que funciona bastante bien cuidado.
fuente
FileInputStream con InputStreamReader es mejor que usar directamente FileReader, porque este último no le permite especificar el conjunto de caracteres de codificación.
Aquí hay un ejemplo usando BufferedReader, FileInputStream y InputStreamReader juntos, para que pueda leer las líneas de un archivo.
fuente
Para otro como idiomas latinos, por ejemplo cirílico, puede usar algo como esto:
y asegúrese de que su
.txt
archivo se guarde con el formatoUTF-8
(pero no como predeterminadoANSI
). ¡Salud!fuente