Java para programadores(4.6a). Entradas y salidas.Streams

Los flujos de datos

Un programa necesita datos para funcionar; es más, el objetivo de todo programa es recibir unos datos, manejarlos y trabajar con ellos, para, finalmente, entregarlos. En Java, todos esos datos son flujos que provienen de una entrada, o se dirigen a una salida, y el paquete java.io dispone de las herramientas para recibir esos flujos desde un dispositivo de entrada, y mandarlos a un dispositivo de salida

Por medio de este paquete podemos enviar y recibir datos, conocidos por streams, por cualquier entrada/salida, ya sea teclado, red o disco, y tanto en modo byte como en modo carácter. Los streams es una abstracción de todo aquello que consuma o facilite información. También los podemos ver como flujos de bytes que llegan de un dispositivo, o se dirigen a uno.

Las clases del paquete java.io establecen la relación entre los streams y los dispositivos; de esta forma podemos utilizar las mismas instrucciones para manejarlos, independientemente que sean para Consola, Impresoras, discos, red,…

Java trabaja con dos tipos de Streams:

Streams de byte, pensados para la gestión de datos binarios y tratados por InputStream y OutputStream

Streams de carácter. Pensados para la entrada/salida de datos con formato carácter y son tratados por Reader y Writer

Flujos binarios – Streams de byte (8 bits)

Es el Sistema de flujo básico; el resto de tipo de flujo están construidos sobre este. Al final, todo flujo de datos está construido a base de flujos de bytes. Nos va a permitir trabajar con datos tales como archivos de imagen, de sonido. Etc.

Las  clases que utilizaremos para manejarlos heredarán de las clases abstractas InputStream y OutputStream

Flujos de caracteres – Streams de char(16 bits)

Este flujo, está pensado para trabajar con texto plano, ya que trata caracteres Unicode y soporta internacionalización. Como hemos indicado antes, aunque la acción física se realice a nivel de byte, estas clases se encargan de realizar la conversión de byte a char en entradas, y de char a  byte en salida.

Las clases abstractas de las que heredan el resto de clases que vamos a utilizar, son Reader y Writer

Flujos estándares

System.in

  • Instancia de la clase InputStream: flujo de bytes de entrada, conectado al dispositivo de entrada estándar del sistema (normalmente, la consola)
  • Métodos de lectura
    • read() permite leer un byte de la entrada como entero
    • skip(n ) ignora n bytes de la entrada
    • available() número de bytes disponibles para leer en la entrada

System.out

  • Instancia de la clase PrintStream: flujo de bytes de salida conectado al dispositivo de salida del sistema(normalmente, la consola)
  • Métodos para impresión de datos
    • print(), println() graba sin/con avance de línea
    • flush() vacía el buffer de salida escribiendo su contenido

System.err

  • Idéntico funcionamiento que System.out, pero conectado al dispositivo físico de salida de errores (normalmente, la consola)

La clase OutputStream – Salida de datos

Clase abstracta para la salida de información, de la que heredan:

  • java.io.OutputStream(implements java.io.Closeable, java.io.Flushable)
    • java.io.ByteArrayOutputStream
      • Graba los datos en una matriz de tipo byte que crece a medida que se va escribiendo. Los datos se pueden recuperar por medio de toByteArray(), y toString()
    • java.io.FileOutputStream
      • Graba los datos en un fichero o en un descriptor de fichero. Según la plataforma, el fichero se puede crear al grabar. FileOutputStream está diseñado para escribir flujos de bytes sin formato, como datos de imágenes.
    • java.io.FilterOutputStream – Esta clase es la superclase de todas las clases que filtran los flujos de salida.
      • java.io.BufferedOutputStream
        • Implementa un buffer de salida para evitar tener que invocar continuamente al sistema de salida subyacente para cada byte
      • java.io.DataOutputStream(implements java.io.DataOutput)
        • Permite escribir en salida los tipos de datos primitivos en una secuencia tal que puedan ser leídos con un stream de entrada
      • java.io.PrintStream(implements java.lang.Appendable, java.io.Closeable)
        • Todos los caracteres impresos por PrintStream se convierten a bytes utilizando la codificación de caracteres predeterminada de la plataforma.
      • java.io.ObjectOutputStream(implements java.io.ObjectOutput, java.io.ObjectStreamConstants)
        • Graba cualquier objeto que implemente Serialize. Los objetos podrán ser recogidos por el stream de entrada correspondiente, devolviendo el mismo objeto que se grabo
      • java.io.PipedOutputStream
        • Permite conectar con un PipedInputStream para establecer una comunicación continua con otro objeto en otra hebra.

La clase InputStream – Entrada de datos

Clase abstracta para la entrada de información, de la que heredan:

  • java.io.InputStream (implements java.io.Closeable) , java.io.ByteArrayInputStream
    • java.io.FileInputStream
      • Recepción de datos desde un fichero o un descriptor de ficheros
    • java.io.FilterInputStream
      • Se utiliza para interceptar los datos de entrada y así aplicar alguna funcionalidad o conversión
      • java.io.BufferedInputStream
        • Permite crear un buffer de entrada en donde se almacenan los datos leídos del sistema subyacente y se van facilitando a medida que se soliciten
      • java.io.DataInputStream(implements java.io.DataInput)
        • Permite leer datos de tipo primitivo, grabados por DataOutputStream
      • java.io.LineNumberInputStream
        • Añade la funcionalidad de facilitar el número de línea que se está leyendo, utilizando las marcas de retorno de carro o de nueva línea para identificar las líneas
      • java.io.PushbackInputStream
        • Añade la funcionalidad de volver atrás el indicador de posición de lectura, para volver a leer bytes que ya habían sido leídos
      • java.io.ObjectInputStream(implements java.io.ObjectInput, java.io.ObjectStreamConstants)
        • Lee datos serializados por ObjectOutputStream y devuelve los objetos originales que los crearon
      • java.io.PipedInputStream
        • Se debe conectar a un stream creado por PipedOutputStream para recibir los datos generados por el otro proceso
      • java.io.SequenceInputStream
        • Representa una colección ordenada de InputStream que serán leídas secuencialmente. Cuando acabe una, pasa a leer la siguiente

Escritura con PrintStream – Salida de datos

La clase java.io.PrintStream esta dentro del grupo considerado filtros. (Hereda de java.io.FilterOutputStream), por lo que nos permite añadir comportamientos a cualquier OutputStream, en su caso: la interpretación de los bytes según el juego de caracteres

Constructores

  • PrintStream(File file)
    • Crea un PrintStream sobre el fichero especificado
  • PrintStream(File file, String csn)
    • Crea un PrintStream sobre el fichero especificado y el charset indicado
  • PrintStream(OutputStream out)
    • Crea un nuevo PrintStream sobre el OutputStream indicado
  • PrintStream(String fileName)
    • Crea un PrintStream sobre el fichero especificado por nombre
  • PrintStream(String fileName, String csn)
    • Crea un PrintStream sobre el fichero especificado por nombre y el charset indicado

Métodos

De momento, vamos a tener en cuenta los método:

  • print(cualquier tipo) – envía el dato a salida, pero no avanza línea
  • println(cualquier tipo) – envía el dato a salida y avanza una línea

Escritura con PrintStream

  • Para poder realizar cualquier salida, deberemos empezar estableciendo el dispositivo de salida
  • Para las primeras pruebas, utilizaremos los definidos por el sistema
    • System.out  Salida a la consola del sistema
    • System.err  Salida al dispositivo de error (normalmente, también la consola
  • Estos dos métodos, proporcionan un objeto PrintStream directamente, por lo que podemos utilizar a nuestra discreción los métodos que ya conocemos

  • Imprime la palabra Día, seguida por el contenido de la variable “día” en una sola línea
  • Por otra parte, podríamos hacer

  • Nos presentaria

  • Esto ocurre porque el método print no realiza el avance de línea
  • Como PrintStream hereda de OutputStream,y out es un PrintStream, tambien es un OutputStream, por lo que también podemos hacer

 

En el siguiente post, veremos como podemos editar con System.out.format

Acerca de Miguel Garcia

Programador, Desarrollador web, Formador en distintas areas de informatica y director de equipos multidisciplinares.
Esta entrada fue publicada en Formacion, Java. Guarda el enlace permanente.

Deja un comentario