2011-04-23 9 views
26

La diferencia entre InputStream y InputStreamReader es que InputStream dice lo byte, mientras InputStreamReader dice lo char. Por ejemplo, si el texto de un archivo es abc, ambos funcionan bien. Pero si el texto es a你们, que se compone de un a y dos caracteres chinos, entonces el InputStream no funciona.La diferencia entre InputStream y InputStreamReader al leer caracteres de múltiples bytes

Así que debemos utilizar InputStreamReader, pero mi pregunta es:

¿Cómo InputStreamReader reconocer caracteres?

a es un byte, pero un carácter chino tiene dos bytes. Qué se lee a como un byte y reconocer al otro de los personajes como dos bytes, o para cada carácter en este texto, ¿el InputStreamReader lo leen como dos bytes?

Respuesta

23

Un InputStream lee octeto de datos en bruto (8 bits). En Java, el tipo byte es equivalente al tipo char en C. En C, este tipo se puede usar para representar datos de caracteres o datos binarios. En Java, el tipo char comparte mayores similitudes con el tipo C wchar_t.

Un InputStreamReader entonces va a transformar datos de algunos de codificación en UTF-16. Si "a 你们" está codificado como UTF-8 en el disco, será la secuencia de bytes 61 E4 BD A0 E4 BB AC. Cuando se pasa el InputStream-InputStreamReader con la codificación UTF-8, que se lee como la secuencia de carbón 0061 4F60 4EEC.

La codificación de caracteres API en Java contiene los algoritmos para llevar a cabo esta transformación. Puede encontrar una lista de codificaciones compatibles con Oracle JRE here. El ICU project es un buen lugar para comenzar si quieres entender los aspectos internos de cómo funciona esto en la práctica.

Como Alexander Pogrebnyak points out, casi siempre debe proporcionar la codificación explícitamente. byte -a- char métodos que no especifican una codificación se basan en la JRE default, que depende de los sistemas operativos y las configuraciones del usuario.

10

usted tiene que dar lector de una pista, proporcionando un juego de caracteres que el archivo binario está escrito en. Por ejemplo

Reader reader = 
    new InputStreamReader(
     new FileInputStream("/path/to/file"), 
     "UTF-8" // most likely that the encoding of the file 
    ) 

Sin una pista que utilizará la codificación predeterminada plataforma, que en muchos casos no es Lo que quieras.

Este enlace tiene una buena explicación de codificaciones: http://www.joelonsoftware.com/articles/Unicode.html

Cuestiones relacionadas