Streams de Caracteres con ejemplos en Java

Avanzado

Como se muestra en las secciones anteriores, las secuencias de bytes de Java son potentes y flexibles. Sin embargo, no son la forma ideal de manejar E/S basadas en caracteres. Para este propósito, Java define las clases de flujo de caracteres.

Lectura Recomendada
Entrada y Salida de datos con Streams

1. Métodos de Streams de Caracteres

En la parte superior de la jerarquía de flujos de caracteres están las clases abstractas Reader y Writer. Las siguientes tablas muestran los métodos de Reader y Writer.

1.1. Métodos Reader

Tabla 1:

Tabla 1: Métodos streams de caracteres definidos por Reader.
MétodoDescripción
abstract void close()Cierra la fuente de entrada. Los intentos de lectura posteriores generarán un IOException.
void mark(int numChars)Coloca una marca en el punto actual del flujo de entrada que seguirá siendo válida hasta que se lean los caracteres numChars.
boolean markSupported()Devuelve true si mark()/reset() son compatibles en este flujo.
int read()Devuelve una representación entera del siguiente carácter disponible desde el flujo de entrada invocado. -1 se devuelve cuando se intenta leer al final del flujo.
int read(chat buffer[])Intente leer los caracteres buffer.length en el búfer y devuelve el número real de caracteres que se leyeron con éxito. -1 se devuelve cuando se intenta leer al final del flujo.
abstract int read(char buffer[], int offset, int numChars)Intenta leer los caracteres numChars en el búfer comenzando en el búfer [offset], devolviendo la cantidad de caracteres que se leyeron con éxito. -1 se devuelve cuando se intenta leer al final del flujo.
int read (CharBuffer buffer)Intenta llenar el búfer especificado por el búfer, devolviendo la cantidad de caracteres leídos con éxito. -1 se devuelve cuando se intenta leer al final del flujo. CharBuffer es una clase que encapsula un flujo de caracteres, como una cadena.
boolean ready()Devuelve true si la siguiente solicitud de entrada no esperará. De lo contrario, es devuelto false.
void reset()Restablece el puntero de entrada a la marca establecida previamente.
long skip(long numChars)Omite los caracteres de entrada numChars, devolviendo la cantidad de caracteres omitidos.

1.1. Métodos Writer

Tabla 2:

Tabla 2: Métodos streams de caracteres definidos por Writer.
MétodoDescripción
Writer append(char ch)Se agrega ch al final del flujo de salida de invocación. Devuelve una referencia al flujo de invocación.
Writer append(CharSequence chars)Agrega caracteres al final del flujo de salida de invocación. Devuelve una referencia a la secuencia de invocación. CharSequence es una interfaz que define operaciones de solo lectura en un flujo de caracteres.
Writer append(CharSequence chars, int begin, int end)Añade la secuencia de caracteres comenzando desde begin y deteniéndose con end hasta el final del flujo de salida de invocación. Devuelve una referencia al flujo de invocación. CharSequence es una interfaz que define operaciones de solo lectura en un flujo de caracteres.
abstract void close()Cierra el flujo de salida. Los intentos posteriores de escritura generarán una IOException
abstract void flush()Hace que cualquier salida que se haya almacenado en el búfer se envíe a su destino. Es decir, vacía el buffer de salida.
void write(int ch)Escribe un solo caracter en el flujo de salida invocante. Tenga en cuenta que el parámetro es un int, que le permite llamar a write() con expresiones sin tener que volver a convertirlas en char.
void write(char buffer[])Escribe una matriz completa de caracteres en el flujo de salida invocante.
abstract void write (char buffer[], int offset, int numChars)Escribe un subintervalo de caracteres numChars del búfer de la matriz, comenzando en el búfer (offset) al flujo de salida invocante.
void write (String str)Escribe str en el flujo de salida invocante.
void write (String str, int offset, int numChars)Escribe un subrango de caracteres numChars desde la matriz str, comenzando en el offset especificado.

La mayoría de los métodos pueden arrojar una IOException en caso de error. Los métodos definidos por estas dos clases abstractas están disponibles para todas sus subclases. Por lo tanto, forman un conjunto mínimo de funciones de E/S que tendrán todas los flujos de caracteres.

2. Entrada de consola con Streams de caracteres

Para el código que se internacionalizará, la introducción desde la consola mediante los flujos basados en caracteres de Java es una manera mejor y más conveniente de leer caracteres del teclado que utilizando los streams de bytes.

Sin embargo, dado que System.in es un flujo de bytes, deberá ajustar System.in dentro de algún tipo de Reader. La mejor clase para leer la entrada de la consola es BufferedReader, que admite un flujo de entrada en búfer. Sin embargo, no puede construir un BufferedReader directamente desde System.in. En cambio, primero debe convertirlo en un flujo de caracteres. Para hacer esto, usará InputStreamReader, que convierte bytes en caracteres. Para obtener un objeto InputStreamReader que esté vinculado a System.in, use el constructor que se muestra a continuación:

InputStreamReader(InputStream inputStream)

Como System.in se refiere a un objeto de tipo InputStream, se puede usar para inputStream.

Luego, usando el objeto producido por InputStreamReader, construye un BufferedReader usando el constructor que se muestra aquí:

BufferedReader(Reader inputReader)

Aquí, inputReader es la secuencia que está vinculada a la instancia de BufferedReader que se está creando. Poniéndolo todo junto, la siguiente línea de código crea un BufferedReader que está conectado al teclado.

BufferedReader br= new BufferedReader (new InputStreamReader (System.in));

Después de que se ejecute esta instrucción, br será un stream basado en caracteres que está vinculada a la consola a través de System.in.

3. Lectura de caracteres

Los caracteres se pueden leer desde System.in utilizando el método read() definido por BufferedReader de forma muy parecida a como se leyeron utilizando flujos de bytes. Aquí hay tres versiones de read() soportadas por BufferedReader.

int read() throws IOException
int read(char data[]) throws IOException
int read(char data[], int start, int max) throws IOException
  • La primera versión de read() lee un único carácter Unicode. Devuelve -1 cuando se intenta leer al final del flujo.
  • La segunda versión lee caracteres desde la entrada de flujo y los pone en data hasta que la matriz está llena, se llega al final del flujo o se produce un error. Devuelve la cantidad de caracteres leídos o -1 cuando se intenta leer al final de la secuencia.
  • La tercera versión lee la entrada en data comenzando en la ubicación especificada por start. Se almacenan hasta max de caracteres. Devuelve la cantidad de caracteres leídos o -1 cuando se intenta leer al final de la secuencia.
  • Todos lanzan una IOException en caso de error. Cuando se lee desde System.in, al pulsar INTRO se genera una condición de fin de flujo.

El siguiente programa muestra read() leyendo caracteres de la consola hasta que el usuario escriba un punto. Tenga en cuenta que cualquier excepción de E/S que pueda generarse simplemente se descarta de main(). Como se mencionó anteriormente, este enfoque es común cuando se lee desde la consola. Por supuesto, puede manejar este tipo de errores bajo el control del programa, si lo desea.

//Uso de BufferedReader para leer caracteres de la consola
import java.io.*;

class LeerCaracteres {
    public static void main(String[] args) throws IOException {
        char c;
        BufferedReader br= new
                BufferedReader(new InputStreamReader(System.in));
        System.out.println("Ingrese caracteres, sequido de punto para parar.");

        //Leer Caracteres
        do {
            c=(char)br.read();
            System.out.println(c);
        }while (c!='.');
    }
}

Salida:

Ingrese caracteres, sequido de punto para parar.
java.
j
a
v
a
.

4. Lectura de Strings

Para leer una cadena/string desde el teclado, use la versión de readLine() que es miembro de la clase BufferedReader. Su forma general se muestra aquí:

String readLine() throws IOException

Devuelve un objeto String que contiene los caracteres leídos. Devuelve null si se intenta leer cuando está al final del flujo.

El siguiente programa muestra BufferedReader y el método readLine(). El programa lee y muestra líneas de texto hasta que ingrese la palabra “detener”.

//Leer una cadena desde la consola usando BufferedReader
import java.io.*;
class ReadLines {
    public static void main(String[] args) throws IOException{
        //Creando un BufferedReader usando System.in
        BufferedReader br=new BufferedReader(new
                InputStreamReader(System.in));
        String str;

        System.out.println("Ingrese una línea de texto.");
        System.out.println("Ingrese 'detener' para detener el programa.");
        do {
            str=br.readLine();
            System.out.println(str);
        }while (!str.equals("detener"));
    }
}

5. Salida de consola utilizando flujo de caracteres

Aunque todavía es permisible usar System.out para escribir en la consola bajo Java, su uso se recomienda principalmente para propósitos de depuración o para programas de ejemplo como los que se encuentran en este curso.

Para programas del mundo real, el método preferido para escribir en la consola cuando se utiliza Java es a través de una secuencia PrintWriter. PrintWriter es una de las clases basadas en caracteres. Como se explicó, el uso de una clase basada en caracteres para la salida de la consola facilita la internacionalización del programa.

PrintWriter define varios constructores. La que usaremos se muestra aquí:

PrintWriter(OutputStream outputStream, boolean flushingOn)

Aquí, outputStream es un objeto de tipo OutputStream y flushingOn controla si Java vacía el flujo de salida cada vez que se llama a un método println() (entre otros). Si flushingOn es true, el flushing se produce automáticamente. Si es false, el flushing no es automático.

PrintWriter admite los métodos print() y println() para todos los tipos, incluido Object. Por lo tanto, puede usar estos métodos exactamente de la misma manera en que se usaron con System.out. Si un argumento no es de tipo primitivo, los métodos PrintWriter llamarán al método toString() del objeto y luego imprimirán el resultado.

Para escribir en la consola con PrintWriter, especifique System.out para el flujo de salida y purgue la secuencia después de cada llamada a println(). Por ejemplo, esta línea de código crea un PrintWriter que está conectado a la salida de la consola.

PrintWriter pw = new PrintWriter(System.out, true);

La siguiente aplicación muestra el uso de PrintWriter para manejar la consola salida.

//Demostración de PrintWriter
import java.io.*;

class PrintWriterDemo {
    public static void main(String[] args) {
        PrintWriter pw=new PrintWriter(System.out, true);
        int i=10;
        double d=123.65;

        pw.println("Usando PrintWriter.");
        pw.println(i);
        pw.println(d);

        pw.println(i + " + " + d + " es " + (i+d));
    }
}

Salida:

Usando PrintWriter.
10
123.65
10 + 123.65 es 133.65

Recuerde que no hay nada de malo en utilizar System.out para escribir una salida de texto simple en la consola cuando esté aprendiendo Java o depurando sus programas. Sin embargo, usar un PrintWriter hará que sus aplicaciones del mundo real sean más fáciles de internacionalizar.

6. E/S de Archivos utilizando flujo de caracteres

Aunque el manejo de archivos orientado a bytes es el más común, es posible usar flujos basados en caracteres para este propósito. La ventaja del flujo de caracteres es que operan directamente en caracteres Unicode. Por lo tanto, si desea almacenar texto Unicode, las secuencias de caracteres son sin duda su mejor opción. En general, para realizar E/S de archivos basada en caracteres, usará las clases FileReader y FileWriter.

6.1. Usando FileWriter

FileWriter crea un Writer que se puede usar para escribir en un archivo. Aquí se muestran dos constructores de uso común:

FileWriter(String nombreArchivo) throws IOException
FileWriter(String nombreArchivo, boolean append) throws IOException

Aquí, nombreArchivo es el nombre completo de la ruta de un archivo. Si append es true, la salida se agrega al final del archivo. De lo contrario, el archivo se sobrescribe. O lanza una IOException en caso de error. FileWriter se deriva de OutputStreamWriter y Writer. Por lo tanto, tiene acceso a los métodos definidos por estas clases.

Aquí hay una utilidad simple de clave a disco que lee las líneas de texto ingresadas en el teclado y las escribe en un archivo llamado “Prueba.txt”. El texto se escribe hasta que el usuario ingrese la palabra “detener”. Utiliza un FileWriter para mostrar el archivo.

import java.io.*;

class FileWriterDemo {
    public static void main(String[] args) {
        String str;
        BufferedReader br=new BufferedReader(new
                InputStreamReader(System.in));
        System.out.println("Ingrese texto ('detener' para salir)");

        try(FileWriter fw=new FileWriter("Prueba.txt"))//Crea un FileWriter
        {
            do {
                System.out.println(": ");
                str=br.readLine();

                if (str.compareTo("detener")==0) break;
                str=str+"\r\n"; //Añadir nueva línea
                fw.write(str);
            }while (str.compareTo("detener")!=0);
        } catch (IOException e) {
            System.out.println("Error de E/S: "+e);
        }
    }
}

Salida:

Uso de FileWriter en Java
Uso de FileWriter en Java

6.2. Usando FileReader

La clase FileReader crea un Reader que puede usar para leer el contenido de un archivo. Un constructor de uso común se muestra aquí:

FileReader(String nombreArchivo) throws FileNotFoundException

Aquí, nombreArchivo es el nombre completo de la ruta de un archivo. Lanza un FileNotFoundException si el archivo no existe. FileReader se deriva de InputStreamReader y Reader. Por lo tanto, tiene acceso a los métodos definidos por estas clases.

El siguiente programa crea una sencilla utilidad que lee un archivo de texto llamado “Prueba.txt” y muestra su contenido en la pantalla.

//Demostración de FileReader

import java.io.*;
class FileReaderDemo {
    public static void main(String[] args) {
        String s;

        //Cree y use un FileReader incluido en un BufferedReader.
        try (BufferedReader br=new BufferedReader(new FileReader("Prueba.txt"))){
            while ((s=br.readLine())!=null){
                System.out.println(s);
            }
        }catch (IOException exc){
            System.out.println("Error de E/S: "+exc);
        }
    }
}

Salida:

Uso de FileReader en Java
Uso de FileReader en Java

En este ejemplo, observe que FileReader está incluido en un BufferedReader. Esto le da acceso a readLine(). Además, al cerrar el BufferedReader, br, en este caso, cierra automáticamente el archivo.

E/S en Java
  • Streams de caracteres

Sobre el Autor:

Hey hola! Yo soy Alex Walton y tengo el placer de compartir conocimientos hacía ti sobre el tema de Programación en Java, desde cero, Online y Gratis.

Deja una Respuesta

*

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.