2009-07-01 19 views
7

Tengo una clase de cliente FTP que devuelve InputStream apuntando el archivo. Me gustaría leer el archivo fila por fila con BufferedReader. El problema es que el cliente devuelve el archivo en modo binario y el archivo tiene la codificación ISO-8859-15.BufferedReader devuelve cadena ISO-8859-15 - cómo convertir a cadena UTF16?

+0

No veo cómo está involucrado UTF-8 aquí - Java usa UTF-16 internamente, no UTF-8. –

+0

Lo siento, debería haber dicho UTF-16. Fijo. – tputkonen

Respuesta

21

Si el archivo/arroyo/lo que realmente contenga texto codificado con ISO-8859-15, solo necesita especificarlo cuando cree el InputStreamReader:

BufferedReader br = new BufferedReader(
    new InputStreamReader(ftp.getInputStream(), "ISO-8859-15")); 

Luego, readLine() creará Cadenas válidas en la codificación nativa de Java (que es UTF-16, no UTF-8).

+0

Estoy bastante seguro de que a menos que utilice la forma del constructor que toma un argumento del codificador, no solo una cadena o conjunto de caracteres, no obtendrá una excepción en la entrada mal formada. – tchrist

+0

@tchrist: ¿Está hablando del constructor ISR que toma un argumento CharsetDecoder, correcto? Es cierto que todos los otros ctors crean decodificadores que * reemplazan * los caracteres no válidos en lugar de arrojar excepciones. Pero no creo que un decodificador ISO-8859-15 arrojaría una excepción de todos modos. Todos los valores de bytes posibles se correlacionan con un carácter válido, y esa es la única forma en que podría detectar malformaciones input. –

+0

Sí, así es. El problema es cuando pides UTF-8 y no lo recibes - * y * ¡no obtienes una excepción! De forma similar para el resultado, si (estúpidamente) prefieres la aplicación de la plataforma codificación definitiva, que en la Mac al menos reemplaza los puntos de código no asignables con caracteres '?', nuevamente sin advertencia ni excepción. Estoy acostumbrado a un comportamiento mucho más seguro con Perl en estas áreas, y los valores predeterminados de Java simplemente se rompen. Nuestra base de código completa (la parte de Java, no la parte de Perl) está plagada de errores desagradables debido a esto. Casi te hace desear parchear mono las libs estándar de Java. *Casi*. ☺ – tchrist

1

La cadena original está en ISO-8859-15, por lo que la secuencia de bytes leída por su InputStreamReader estará en esta codificación. Así que lea usando esa codificación (especifique esto en el constructor InputStreamReader). Eso le dice al InputStreamReader que la corriente de bytes entrantes está en ISO-8859-15 y para realizar las conversiones apropiadas de byte a carácter.

Ahora estará en el formato estándar Java UTF-16, y puede hacer lo que desee.

Creo que el problema actual es que lo está leyendo usando su codificación predeterminada (al no especificar una codificación en InputStreamReader) y luego tratando de convertirlo, momento en el que ya es demasiado tarde.

El uso del comportamiento predeterminado para este tipo de clases a menudo termina en duelo. Es una buena idea especificar codificaciones siempre que sea posible, y/o por defecto la codificación VM a través de -Dfile.encoding

+0

Downvoted why? –

+0

Debe haber sido un error, lo siento, es demasiado tarde para deshacer :( – Kieran

0

Ha intentado:

BufferedReader r = new BufferedReader(new InputStreamReader("ISO-8859-1")) 
... 
+0

s/b ISO-8859-15, no ISO-8859-1 – lavinio

9

Prueba esto:

BufferedReader br = new BufferedReader(
         new InputStreamReader(
          ftp.getInputStream(), 
          Charset.forName("ISO-8859-15") 
         ) 
        ); 
String row = br.readLine();