Skip to content

2 Stream estándar

Introducción

En Java, existe una serie de streams comunes a los cuales se les denomina streams standards. El mismo sistema es el encargado de crear dichos streams automáticamente.

  • System-in: Es una instancia de la clase InputStream y tiene métodos que nos permite leer un byte de entrada (read()), ignorar una cantidad de bytes (skip()) y conocer el número de bytes disponibles para leer la entrada.
  • System.out: Es una instancia de la clase PrintStream (hija de OutputStream) y tiene métodos para imprimir los datos, como print() y println(), además del método flush() para vaciar el buffer de salida escribiendo su contenido.
  • System.err: Se utiliza de forma similar al anterior, pero con el objetivo de enviar mensajes de error.

Scanner

Scanner, como ya hemos visto hasta ahora, analiza y escanea la información desde una fuente de datos. Esa fuente de datos era System.in que es la entrada de nuestro sistema.

Sin embargo, el constructor Scanner está sobrecargado de la siguiente manera:

  • Scanner(InputStream source). Recibe una instancia de tipo InputStream como fuente de datos. Al ser System.in una instancia que hereda de InputStream, este es el constructor que hemos estado usando todo el tiempo.
  • Scanner(File source). Recibe un fichero como fuente de datos.
  • Scanner(String source). Recibe la ruta del fichero como una cadena como fuente de datos.

Veamos un ejemplo, para leer un fichero haciendo uso de Scanner:

File file = new File("my_file.txt");
Scanner scanner = new Scanner(file);

while(scanner.hasNext()){
    System.out.println(scanner.nextLine());
}

Salida estándar

La salida estándar System.out por defecto es la consola de nuestro sistema. Sin embargo, podemos modificar este comportamiento, y que toda las salidas que hagamos se muestren en otra fuente de datos, como en un fichero.

Para ello, creamos una nueva instancia de PrintStream con la ruta de la fuente de datos, o cualquier clase hija de OutputStream. Posteriormente, cambiamos la fuente de salida con el método estático System.setOut(PrintStream stream). Veamos un ejemplo:

try {
    PrintStream archivo = new PrintStream("salida.txt");

    System.setOut(archivo);


    System.out.println("Esta línea se guarda en el archivo.");
    System.out.println("Ya no aparece en la consola.");

    archivo.close();
} catch (FileNotFoundException e) {
    System.err.println("Error: no se pudo crear el archivo.");
    e.printStackTrace();
}

Ahora, cada vez que se utilice el método println() se escribe en el fichero salida.txt. Esto es muy útil cuando queramos crear logs de nuestro proyecto.

try (with resources)

La estructura try nos permite manejar los errores, como hemos visto, pero con la estructura try (with resources), no solo nos permitirá manejar los errores, si no nos cerrará los recursos cuando se necesario, evitando así, tener que cerrarlos manualmente. Veamos el ejemplo anterior con un try (with resources):

try (PrintStream archivo = new PrintStream("salida.txt");){
    System.setOut(archivo);


    System.out.println("Esta línea se guarda en el archivo.");
    System.out.println("Ya no aparece en la consola.");
} catch (FileNotFoundException e) {
    System.err.println("Error: no se pudo crear el archivo.");
    e.printStackTrace();
}