InputStreamReader y OutputStreamWriter

Muchas clases de la biblioteca estandar de Java que generan streams, los hacen en modo byte, por lo que si vamos a querer leer o escribir en modo caracter, tendremos que pasar esos streams a través de InputStreamReader y de OutputStreamWriter, que son clases que sirven para hacer la traducción entre un tipo de stream y otro.

Cuando trabajamos con flujos en Java, es fundamental entender cómo manejar la lectura y escritura de datos, especialmente cuando queremos transformar entre flujos binarios y de caracteres. En este sentido, las clases InputStreamReader y OutputStreamWriter resultan esenciales para adaptar un InputStream a un Reader y un OutputStream a un Writer, respectivamente.

Empecemos por la entrada estándar, System.in. Aunque a menudo la usamos para leer texto, en realidad es un flujo binario, un InputStream. Esto significa que Java no sabe de antemano si vamos a leer texto o datos binarios, por lo que lo trata como bytes. Para poder leer texto de forma cómoda, necesitamos convertir ese flujo binario en un flujo de caracteres. Aquí es donde entra en juego InputStreamReader. Esta clase recibe un InputStream como parámetro, por ejemplo System.in, y nos devuelve un Reader, que nos permite leer caracteres en lugar de bytes.

Para hacer la lectura más eficiente y cómoda, es habitual envolver ese InputStreamReader en un BufferedReader. Esto nos permite leer líneas completas o bloques de texto con buffer, mejorando el rendimiento y facilitando la manipulación de cadenas. El patrón típico para leer desde la entrada estándar sería algo así:

try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
    String linea;
    while ((linea = br.readLine()) != null) {
        System.out.println("Leído: " + linea + " (longitud: " + linea.length() + ")");
    }
} catch (IOException e) {
    e.printStackTrace();
}

En este código, el programa se queda esperando a que el usuario escriba algo en la consola. Cuando pulsamos Enter, la línea introducida se envía al System.in, que es leído por el InputStreamReader, convertido a caracteres y finalmente procesado por el BufferedReader. Así podemos imprimir la línea y su longitud, por ejemplo. El programa seguirá leyendo hasta que se envíe una señal de fin de entrada, como Ctrl+D o Ctrl+C, dependiendo del entorno.

Por otro lado, para la salida estándar, System.out es un OutputStream binario. Si queremos escribir texto a través de un Writer, podemos usar OutputStreamWriter, que convierte un OutputStream en un Writer. Esto nos permite enviar cadenas de caracteres que serán transformadas en bytes y enviadas al flujo de salida. Un ejemplo sencillo sería:

try (OutputStreamWriter osw = new OutputStreamWriter(System.out)) {
    osw.write("Hola, ¿cómo estamos?");
    osw.flush();
} catch (IOException e) {
    e.printStackTrace();
}

Aunque en el caso de System.out ya contamos con un PrintStream que facilita la escritura de texto, este ejemplo ilustra cómo podemos usar OutputStreamWriter para conectar un Writer con un OutputStream cualquiera, como podría ser un socket TCP o un archivo.

En definitiva, estas clases nos permiten adaptar flujos binarios a flujos de caracteres y viceversa, facilitando la lectura y escritura de texto en Java de forma flexible y eficiente.

Lista de reproducción
  1. 1
    Introducción al taller
    2 minutos
  2. 2
    Qué es la entrada y salida
    4 minutos
  3. 3
    Streams de entrada y salida en Java
    7 minutos
  4. 4
    FileOutputStream
    9 minutos
  5. 5
    FileInputStream
    13 minutos
  6. 6
    try-with-resources
    2 minutos
  7. 7
    ObjectOutputStream y OutputInputStream
    6 minutos
  8. 8
    Object streams con Strings y Objects
    6 minutos
  9. 9
    Serializando clases
    7 minutos
  10. 10
    Los peligros de Serializable
    4 minutos
  11. 11
    BufferedOutputStream
    6 minutos
  12. 12
    Envolviendo varios OutputStreams
    2 minutos
  13. 13
    BufferedInputStream y rebobinado de streams
    9 minutos
  14. 14
    Readers y Writers en Java
    3 minutos
  15. 15
    Writer y FileWriter
    4 minutos
  16. 16
    Reader, FileReader y BufferedReader
    4 minutos
  17. 17
    InputStreamReader y OutputStreamWriter
    6 minutos
  18. 18
    PrintStream y PrintWriter
    5 minutos