Flujos de E/S en Java

Flujos de E/S

Los flujos de E/S en Java se realizan a través de secuencias ordenadas de bytes (streams)

Estos pueden ser de entrada (InputStream) o de salida (OutputStream) independizando a los objetos de los datos

Las clases de E/S se encuentran en el paquete java.io

Los métodos de OutputStream y de InputStream lanzan la excepción IOException ante cualquier fallo relacionado con el intento de lectura/escritura

La clase OutputStream

Clase abstracta de la que derivan los demás flujos de salida

Fundamentalmente ofrece los siguientes métodos:

  • public abstract void write(int b) throws IOException
  • public void write(byte b[]) throws IOException
  • public void write(byte b[], int off, int len) throws IOException
  • public void flush() throws IOException

    Fuerza la escritura

  • public void close() throws IOException

Hay varias clases que derivan de OutputStream y redefinen el método write para darle una implementación distinta:

  • FileOutputStream

    redefine el método write para enviar bytes a un fichero

  • ByteArrayOutputStream
  • PipedOutputStream
  • Sun.net.TelnetOutputStream

FilterOutputStream

Un filtro de salida es un OutputStream al cual se le asocia en su constructor otro OutputStream (un patrón decorador)

Los filtros reenvían toda la información que reciben a su OutputStream asociado, previa realización de algún tipo de transformación en la misma

De esta manera cada filtro añade una funcionalidad adicional al OutputStream que encapsula

Se pueden encadenar varios filtros para obtener varias funcionalidades combinadas

En el ejemplo se ha cargado el archivo datos.dat para escritura y utilizando el método write se han guardado varios valores enteros que se almacenaban en la variable i

Se le añade & 0xFF al final del flujo de escritura para indicar dentro del fichero, que se ha terminado de escribir un dato

Filtro DataOutputStream

Los métodos de la clase OutputStream solo permiten enviar bytes

Cualquier otro tipo deberá descomponerse en una secuencia de bytes antes de poder escribirse

Entre los métodos más destacados:

  • void writeBytes(String s) throws IOException
  • void writeBoolean(boolean v) throws IOException
  • void writeShort(int v) throws IOException
  • void writeChar(int v) throws IOException
  • void writeInt(int v) throws IOException
  • void writeLong(long v) throws IOException
  • void writeFloat(float v) throws IOException
  • void writeDouble(double v) throws IOException
  • void writeChars(Strings s) throws IOException

    Casi no usado, es más usado el filtro PrintStream

En el ejemplo se han usado dos filtros, el FileOutputStream visto anteriormente y el DataOutputStream visto ahora

La clase DataOutputStream añade la funcionalidad de poder enviar todos los tipos primitivos directamente

Así que podremos escribir en el fichero cualquier tipo primitivo e incluso atributos de un objeto, siempre que sean tipos primitivos, ya que no escribe el objeto completo

Filtro PrintStream

La clase PrintStream añade la funcionalidad de poder enviar todos los tipos primitivos en formato de texto

En el ejemplo se han usado dos filtros, el FileOutputStream visto anteriormente y el PrintStream visto ahora

Los métodos print y println están sobrecargados para todos los tipos primitivos

System.out es de tipo PrintStream y por eso no es necesario referenciarlo al usar este filtro

La forma más habitual de usar OutputStream será combinando varios filtros

La clase InputStream

Clase abstracta de la que derivan los demás flujos de entrada

Fundamentalmente ofrece los siguientes métodos:

  • public abstract int read() throws IOException
  • public int read(byte b[]) throws IOException
  • public int read(byte b[], int off, int len) throws IOException
  • public int available() throws IOException
  • public void close() throws IOException

Hay varias clases que derivan de InputStream y redifinen el método read para darle una implementación distinta:

  • FileInputStream

    redefine el método read para leer bytes de un fichero

  • ByteArrayInputStream
  • StringInputStream
  • SequenceInputStream
  • PipedInputStream
  • Sun.net.TelnetInputStream

FilterInputStream

Un filtro de entrada es un InputStream al cual se le asocia en su constructor otro InputStream

Los filtros devuelven la información que a su vez han leído de su InputStream asociado, previa realización de algún tipo de transformación en la misma

De esta manera cada filtro añade una funcionalidad adicional al InputStream básico

Se pueden encadenar varios filtros para obtener varias funcionalidades combinadas

En el ejemplo se ha cargado el archivo datos.dat para lectura y utilizando el método read se han leido varios valores enteros que se almacenaban en la variable ch en las posiciones i + 1 y los hemos mostrado por pantalla

Así hemos podido leer el archivo que escribimos con el ejemplo de FileOutputStream

Filtro DataInputStream

Los métodos de la clase InputStream solo permiten leer bytes

Cualquier otro tipo deberán leerse como una secuencia de bytes y recomponerse antes de poder utilizarse

Fundamentalmente ofrece los siguientes métodos:

  • readBoolean()
  • readChar()
  • readByte()
  • readShort()
  • readInt()
  • readLong()
  • readFloat()
  • readLong()
  • readFloat()
  • readDouble()
  • readLine()
  • readFully(byte[] b)

En el ejemplo se han usado dos filtros, el FileInputStream visto anteriormente y el DataInputStream visto ahora

La clase DataInputStream añade la funcionalidad de poder recibir todos los tipos primitivos directamente

Lo que nos ha permitido mostrar datos primitivos contenidos en el fichero directamente en la pantalla

Así que leer del fichero cualquier tipo primitivo e incluso atributos de un objeto, siempre que sean tipos primitivos, ya que no lee el objeto completo

La forma más habitual de usar InputStream será combinando varios filtros