it-swarm-es.tech

¿Cómo convertir un Reader en InputStream y un Writer en OutputStream?

¿Hay una manera fácil de evitar tratar con problemas de codificación de texto?

85
Andrei Savu

Realmente no puedes evitar tratar los problemas de codificación de texto, pero existen soluciones existentes:

Solo debes elegir la codificación que prefieras.

42
Peter

Si está comenzando con una cadena también puede hacer lo siguiente:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))
93
Ritesh Tendulkar

Bueno, un Reader trata con caracteres y un InputStream trata con bytes. La codificación especifica cómo desea representar a sus caracteres como bytes, por lo que realmente no puede ignorar el problema. En cuanto a evitar problemas, mi opinión es: elige un juego de caracteres (por ejemplo, "UTF-8") y apégate a él.

Sobre cómo hacerlo realmente, como se ha señalado, "los nombres obvios para estas clases son ReaderInputStream y WriterOutputStream ." Sorprendentemente, "estos no están incluidos en la biblioteca de Java "aunque las clases 'opuestas', InputStreamReader y OutputStreamWriter are included.

Entonces, muchas personas han creado sus propias implementaciones, incluyendo Apache Commons IO . Dependiendo de los problemas de licencia, probablemente podrá incluir la biblioteca commons-io en su proyecto, o incluso copiar una parte del código fuente (que se puede descargar aquí ).

Como puede ver, la documentación de ambas clases indica que "todas las codificaciones de juegos de caracteres compatibles con el JRE se manejan correctamente".

Nótese bien Un comentario en una de las otras respuestas aquí menciona este error . Pero eso afecta la clase Apache Ant ReaderInputStream ( here ), no la clase Apache Commons IO ReaderInputStream.

38
Peter Ford

También tenga en cuenta que, si está comenzando con un String, puede omitir la creación de un StringReader y crear un InputStream en un solo paso usando org.Apache.commons.io.IOUtils from Commons IO al igual que:

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

Por supuesto, aún debe pensar en la codificación del texto, pero al menos la conversión se realiza en un solo paso.

19
Phil Harvey

Utilizar:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

De esta manera no se requiere una conversión inicial a String y luego a byte[], que asigna mucha más memoria de almacenamiento dinámico, en caso de que el informe sea grande. Se convierte en bytes sobre la marcha a medida que se lee el flujo, directamente desde el StringBuffer.

Utiliza CharSequenceInputStream from Apache Commons IO project.

8
Oliv
7
Bozho

No puede evitar problemas de codificación de texto, pero Apache commons-io ha

Tenga en cuenta que estas son las bibliotecas a las que se refiere la respuesta de Peter de koders.com, solo enlaces a la biblioteca en lugar del código fuente.

5
dfrankow

Los nombres obvios para estas clases son ReaderInputStream y WriterOutputStream. Desafortunadamente, estos no están incluidos en la biblioteca de Java. Sin embargo, google es tu amigo.

No estoy seguro de que vaya a solucionar todos los problemas de codificación de texto, que son una pesadilla.

Hay un RFE, pero está cerrado, no se solucionará.

5

¿Estás tratando de escribir el contenido de una Reader a una OutputStream? Si es así, le será más fácil envolver la OutputStream en una OutputStreamWriter y escribir las chars de la Reader a la Writer, en lugar de tratar de convertir al lector a una InputStream

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block
4
Sam Barnum

Puede usar Cactoos (sin métodos estáticos, solo objetos):

Puedes convertir al revés también:

1
yegor256

Una advertencia cuando se utiliza WriterOutputStream: no siempre se maneja la escritura de datos binarios en un archivo correctamente/lo mismo que una secuencia de salida normal. Tuve un problema con esto que me tomó un tiempo localizarlo.

Si puede, recomendaría usar una secuencia de salida como su base, y si necesita escribir cadenas, use un contenedor OUtputStreamWriter alrededor de la secuencia para hacerlo. Es mucho más confiable convertir texto a bytes que al revés, lo cual es probable por qué WriterOutputStream no es parte de la biblioteca estándar de Java

1
romeara