Lectura InputStream como UTF-8

96

Estoy intentando leer de un text/plainarchivo a través de Internet, línea por línea. El código que tengo ahora es:

URL url = new URL("http://kuehldesign.net/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
LinkedList<String> lines = new LinkedList();
String readLine;

while ((readLine = in.readLine()) != null) {
    lines.add(readLine);
}

for (String line : lines) {
    out.println("> " + line);
}

El archivo, test.txtcontiene ¡Hélló!, que estoy usando para probar la codificación.

Cuando reviso el OutputStream( out), lo veo como > ¬°H√©ll√≥!. No creo que esto sea un problema con el OutputStreamya que puedo hacerlo out.println("é");sin problemas.

¿Alguna idea para leer en formato InputStreamUTF-8? ¡Gracias!

Chris Kuehl
fuente
1
El protocolo HTTP especifica la codificación. ¿Por qué no utiliza una API de biblioteca que se encarga de eso por usted? Nunca debería tener que adivinar la codificación de esta manera. No quiero ser negativo: ¡lo estás haciendo genial! Me pregunto si no hay una forma más fácil.
tchrist
1
text/plainDesafortunadamente, no tendré acceso al servidor que está sirviendo el archivo y no está usando una codificación UTF-8. No conocía ninguna buena biblioteca de red; ¿alguna sugerencia?
Chris Kuehl
1
Mirando los documentos , no creo que tenga que especificar la codificación en absoluto. ¡Me sorprende que te den un flujo de bytes! Tiene acceso a URLConnection subyacente , desde el cual puede verificar Content-Encoding, luego abrir un InputStreamReader con el argumento correcto. Una verificación rápida de la fuente no muestra nada que parezca hacer eso por usted, lo que parece bastante tonto y propenso a errores, por lo que probablemente me perdí algo.
tchrist

Respuestas:

189

Resolví mi propio problema. Esta línea:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

necesita ser:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));

o desde Java 7:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
Chris Kuehl
fuente
3
Estoy bastante seguro de que la forma del constructor no generará una excepción en una entrada no válida. Necesitas usar el con un CharsetDecoder decargumento. Este es el mismo error de diseño de Java que tienen los OutputStreamWriterconstructores: solo uno de los cuatro realmente condesciende a decirte cuando algo sale mal. De nuevo, también tienes que usar el elegante CharsetDecoder decargumento. Lo único seguro y sensato es considerar que todos los demás constructores están en desuso, porque no se puede confiar en que se comporten.
tchrist
6
Desde Java 7, es posible escribir proporcionar el conjunto de caracteres como una constante, no como una cadenaStandardCharsets.UTF_8
tobijdc
18
String file = "";

try {

    InputStream is = new FileInputStream(filename);
    String UTF8 = "utf8";
    int BUFFER_SIZE = 8192;

    BufferedReader br = new BufferedReader(new InputStreamReader(is,
            UTF8), BUFFER_SIZE);
    String str;
    while ((str = br.readLine()) != null) {
        file += str;
    }
} catch (Exception e) {

}

Prueba esto,.. :-)

Rohith
fuente
8
En lugar de file + = str, cree un StringBuilder y añádalo. Es posible que el compilador pueda optimizar la adición de cadenas, pero es probable que esté creando mucha basura
seand
2
Si desea convertir un BufferedReader en una cadena, use Apache Commons, no reinvente el habón: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Jaime Marín
8
UTF8 = "utf8", buena variable;)
Nicofisi
7

Me encontré con el mismo problema cada vez que encuentra un carácter especial que lo marca como . para resolver esto, intenté usar la codificación: ISO-8859-1

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("txtPath"),"ISO-8859-1"));

while ((line = br.readLine()) != null) {

}

Espero que esto pueda ayudar a cualquiera que vea esta publicación.

joshua cleveland
fuente
1
¿Podría decirnos cuáles son los caracteres que no se admiten en UTF-8?
USM