¿Hay alguna manera fácil de evitar problemas de codificación de texto?¿Cómo convertir un lector a InputStream y un escritor en OutputStream?
Respuesta
Realmente no se puede evitar tratar con los problemas de codificación de texto, pero hay soluciones existentes:
Reader
aInputStream
:ReaderInputStream
Writer
-OutputStream
:WriterOutputStream
Sólo necesita elegir la codificación que elijas.
Los nombres obvios para estas clases son ReaderInputStream y WriterOutputStream. Lamentablemente, estos no están incluidos en la biblioteca de Java. Sin embargo, google es tu amigo.
No estoy seguro de que va a solucionar todos los problemas de codificación de texto, que son una pesadilla.
There is an RFE, pero está cerrado, no se solucionará.
https://bugs.openjdk.java.net/browse/JDK-4103785 contiene comentarios "tenemos una API pública para el juego de caracteres de codificación ... ninguna razón de peso para agregar estos clases "- entonces, ¿cómo se hace esto en Java 7, sin bibliotecas adicionales, doce años en el futuro? –
¿Está tratando de escribir el contenido de un Reader
en un OutputStream
? Si es así, tendrá un tiempo más fácil envolver el OutputStream
en un OutputStreamWriter
y escribe los char
s de la Reader
a la Writer
, en lugar de tratar de convertir al lector a un 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
nota también de que, si estás empezando con una cadena, puede omitir la creación de un StringReader y crear un InputStream en un solo paso utilizando org.apache.commons.io.IOUtils de Commons IO así:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
por supuesto que aún necesita pensar en la codificación de texto, pero en lea st la conversión está sucediendo en un solo paso.
Este método básicamente hace 'nuevo ByteArrayInputStream (report.toString(). GetBytes ("utf-8")) ', que implica la asignación de dos copias adicionales del informe en la memoria. Si el informe es grande, es incorrecto. Consulte mi respuesta. – Oliv
Si usted está comenzando con una cadena que también puede hacer lo siguiente:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
Esto resuelve una problema con la cadena, pero no con la original – sbeliakov
La buena implementación de 'ReaderInputStream' requeriría menos memoria, no debería haber necesidad de almacenar todos los bytes en una matriz a la vez. –
Me gusta esta solución porque funciona cuando se necesita unidad código de prueba que acepta entrada en (por ejemplo) entrada estándar. –
No se puede evitar problemas de codificación de texto, pero tiene Apache commons-io
Tenga en cuenta que estas son las bibliotecas a las que se hace referencia en la respuesta de Peter de koders.com, solo enlaces a la biblioteca en lugar de código fuente.
Bueno, un lector se ocupa de los caracteres y un InputStream se ocupa de los bytes. La codificación especifica cómo deseas representar a tus personajes como bytes, por lo que no puedes ignorar el problema. En cuanto a evitar problemas, mi opinión es: elija un juego de caracteres (por ejemplo, "UTF-8") y quédese con él.
con respecto a cómo lo hacen realmente, como se ha señalado, "los nombres obvios para estas clases son ReaderInputStream y WriterOutputStream." Sorprendentemente, "éstos no están incluidos en la biblioteca de Java" aunque las clases 'opuestas', InputStreamReader y OutputStreamWriterson incluidas.
Por lo tanto, mucha gente ha creado sus propias implementaciones, incluyendo ApacheCommons IO. Según los problemas de licencia, es probable que pueda incluir la biblioteca commons-io en su proyecto, o incluso copiar una parte del código fuente (que se puede descargar here).
- Apache ReaderInputStream: API/source code direct link
- Apache WriterOutputStream: API/source code direct link
Como se puede ver, la documentación de ambas clases afirma que "todas las codificaciones de juegos de caracteres soportados por el JRE se manejan correctamente" .
N.B. Un comentario sobre una de las otras respuestas aquí menciona this bug. Pero eso afecta al Apache Ant clase ReaderInputStream (here), no Apache Commons IO clase ReaderInputStream.
Una advertencia cuando se utiliza WriterOutputStream - no siempre maneja la escritura de datos binarios a un archivo correctamente/lo mismo que una secuencia de salida normal. Tuve un problema con esto que me llevó un tiempo rastrear.
Si puede, recomiendo 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 fiable para convertir texto en bytes que el revés, que es probable por la WriterOutputStream no es una parte de la biblioteca estándar de Java
Uso:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
De esta manera no requiere un adelantado conversión a String
y luego a byte[]
, que asigna mucho más memoria de montón, en caso de que el informe sea grande. Se convierte en bytes sobre la marcha a medida que se lee la secuencia, directamente desde StringBuffer.
Utiliza CharSequenceInputStream del proyecto Apache Commons IO.
Para leer una cadena en una secuencia con solo lo que Java suministra.
InputStream s = new BufferedInputStream(new ReaderInputStream(new StringReader("a string")));
ReaderInputStream se encuentra en Apache Commons IO. –
Puede utilizar Cactoos (no hay métodos estáticos, sólo objetos):
Se puede convertir el revés también:
- 1. Cómo convertir un InputStream a un DataHandler?
- 2. Byte [] a InputStream o OutputStream
- 3. ¿Cómo puedo convertir un InputStream sin comprimir en un InputStream gzip'ed de manera eficiente?
- 4. ¿Cómo puedo convertir un objeto a Inputstream
- 5. Cómo convertir javax.xml.transform.Source en un InputStream?
- 6. ¿Hay un bloqueo delgado de lector/escritor para .NET 2.0?
- 7. Cómo convertir byte [] a InputStream?
- 8. Cómo convertir InputStream a FileInputStream
- 9. ¿Por qué InputStream y OutputStream implementan Cerrar y Socket no?
- 10. Cómo convertir un lector de datos a datatable
- 11. ¿Hay una forma equivalente C# para Java InputStream y OutputStream?
- 12. ¿Convierte un StreamWriter a OutputStream en java?
- 13. ¿Cómo puedo separar una secuencia de un lector de flujo o un escritor de flujo?
- 14. Convertir InputStream en BufferedReader
- 15. Convertir InputStream (Imagen) a ByteArrayInputStream
- 16. ¿Cómo se puede canalizar un OutputStream a un StreamingDataHandler?
- 17. Cómo pasar zócalo, InputStream, objetos OutputStream entre las actividades
- 18. Buscando una estructura de un solo lector de un solo escritor sin bloqueo RT-safe
- 19. forma más eficiente de crear InputStream de OutputStream
- 20. Cerradura de lector/escritor entre procesos con Boost
- 21. Cómo clonar un InputStream?
- 22. ¿Cómo convierto un InputStream a una cadena en Java?
- 23. El lector/escritor JSON más rápido para C++
- 24. Cómo escribir cadenas en un OutputStream
- 25. ¿Cómo escribo en un OutputStream usando DefaultHttpClient?
- 26. Cómo convertir StringBuffer a InputStream en Java ME?
- 27. redireccionar std :: cout a un escritor personalizado
- 28. Descomprimir un archivo de InputStream y devolver otro InputStream
- 29. Convertir datatable a lector de datos
- 30. ¿Cómo poner datos de un OutputStream en un ByteBuffer?
FYI: el código ReaderInputStream tiene un error en la forma en que lee los bytes (no funcionará para todas las codificaciones). Prueba: http://illegalargumentexception.blogspot.com/2009/05/java-rough-guide-to-character-encoding.html#javaencoding_stringclass Hay un error abierto: https://issues.apache.org/bugzilla/show_bug .cgi? id = 40455 – McDowell
También el código es copyright :( – Armand
Puede encontrar las clases en la biblioteca commons-io de Apache: http://commons.apache.org/proper/commons-io/ –