2009-03-30 12 views
108

Intenté usar java.io.FileReader para leer algunos archivos de texto y convertirlos en una cadena, pero encontré que el resultado está mal codificado y no se puede leer en absoluto.Problema de codificación Java FileReader

Aquí es mi medio ambiente:

  • Windows 2003, OS codificación: CP1252

  • Java 5,0

Mis archivos son codificación UTF-8 o CP1252 codificada, y algunos de ellos (archivos codificados en UTF-8) pueden contener caracteres chinos (no latinos).

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. Encontré 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 el carácter de codificación por defecto y el tamaño de memoria intermedia de bytes por defecto son apropiado.

¿Esto significa que no estoy obligado a establecer la codificación de caracteres por mí mismo si estoy utilizando FileReader? Pero obtuve datos codificados incorrectos actualmente, ¿cuál es la forma correcta de lidiar con mi situtaion? Gracias.

+0

También debe perder String.valueOf() dentro del ciclo y usar StringBuffer.append (char [], int, int) directamente. Esto ahorra una gran cantidad de copia del char []. También reemplace StringBuffer con StringBuilder. Sin embargo, nada de esto tiene que ver con tu pregunta. –

+1

Odio decirlo, pero ¿has leído el JavaDoc justo después de la parte que pegaste?Ya sabes, la parte que dice "Para especificar estos valores tú mismo, construye un InputStreamReader en un FileInputStream". – Powerlord

+0

Gracias por su comentario, en realidad leo el JavaDoc, pero de lo que no estoy seguro es si debo especificar estos valores o no, y cambiar a "construir un InputStreamReader en un FileInputStream". – nybon

Respuesta

198

Sí, usted necesita especificar la codificación del archivo que desea leer.

Sí, esto significa que tiene que saber la codificación del archivo que desea leer.

No, no hay una forma general de suponer la codificación de un archivo de "texto sin formato" dado.

The constructors of FileReader utilice siempre la codificación predeterminada de la plataforma que generalmente es una mala idea.

En lugar de FileReader necesita usar new InputStreamReader(new FileInputStream(pathToFile), <encoding>).

+1

InputStream es = new FileInputStream (nombre de archivo); Aquí recibí el error de error de archivo no encontrado con el nombre de archivo ruso –

+2

+1 para la sugerencia de utilizar InputStreamReader, sin embargo el uso de enlaces en bloques de código hace que sea difícil copiar y pegar el código, si esto puede cambiarse, thx – Ferrybig

+0

¿Sería? " UTF-8 "o" UTF8 "en las codificaciones. De acuerdo con [la referencia Java SE en la codificación] (https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html), ya que 'InputStreamReader' es un' java.io 'clase, sería" UTF8 "? – NobleUplift

71

FileReader usa la codificación predeterminada de plataforma de Java, que depende de la configuración del sistema de la computadora en la que se ejecuta y generalmente es la codificación más popular entre los usuarios de esa localidad.

Si esta "mejor suposición" no es correcta, entonces debe especificar la codificación explícitamente. Desafortunadamente, FileReader no permite esto (supervisión mayor en la API). En su lugar, debe usar new InputStreamReader(new FileInputStream(filePath), encoding) e idealmente obtener la codificación de metadatos sobre el archivo.

+17

"gran descuido en la API" - gracias por esta explicación - ¡Me preguntaba por qué no podía encontrar el constructor que buscaba! Cheers John – monojohnny

+0

@Bhanu Sharma: ese es un problema de codificación en un nivel diferente, comprueba de dónde obtienes el nombre de archivo, y si está codificado, qué codificación utiliza el compilador. –

+0

uso tanto el nombre de archivo y el código fijo como una cadena, pero el mismo problema me sale ¿qué debo hacer :( –

Cuestiones relacionadas