Io Stream
Io Stream
Io Stream
El término stream (flujo o corriente) representa un flujo de datos dirigiéndose de una fuente
hacia un destino. Es decir: los datos que fluyen entre un programa y un archivo en disco, entre
un archivo y un programa, entre dos programas, etc. son considerados streams.
Un stream puede transportar todo tipo de información: bytes, datos de tipos primitivos u
objetos. El programa que recibe el stream de datos lo hace a través de un input stream. El
programa que emite un stream de datos lo hace a través de un output stream.
Todos los lenguajes de programación definen una entrada y una salida de datos estándar que,
en general, son el teclado y la pantalla (en modo texto). Es decir, podemos leer datos a través
del teclado y escribir datos en la pantalla utilizando la entrada y la salida estándar
respectivamente. En Java, estos streams están representados por los objetos estáticos
System.in, System.out y System.err. Este último representa a la standard error.
Con los métodos setIn, setOut y setErr de la clase System, podemos cambiar la entrada y
salidas estándar que, por defecto, son el teclado (para el primero) y la pantalla (para los
restantes).
System.setErr(stdErr);
{ arr[i] = 0; }
// cierro todo
stdErr.close();
fos.close();
Ejemplo: abrir un archivo y leerlo byte por byte mostrando cada uno de estos en la pantalla.
FileInputStream fi;
s = new FileInputStream(args[0]);
int c = fi
s.read();
while( c!=-1 )
{ System.out.print((char)c);
c = fis.read();
fis.close();
El método read retorna el byte leído. Notemos que el tipo de datos del valor de retorno del
método es int y no byte. Esto se debe a que en Java el tipo de datos byte es signado, por lo
tanto no admite valores superiores a 127. Es decir, el tipo byte admite solo la mitad de los
valores que se pueden representar en 8 bits. Para indicar que se llegó al fi n del archivo (“end
of file” o eof), el método retornará el valor -1.
Internamente, Java almacena los valores de los caracteres usando la convención UNICODE.
Para codificar un carácter, se utilizan 2 bytes. Esto permite que los programas Java puedan
soportar los juegos de caracteres de (prácticamente) todos los idiomas. En el paquete java.io,
se proveen clases a través de las cuales podemos enviar y recibir fl ujos de caracteres para
luego, si fuera necesario, convertirlos a los diferentes conjuntos de caracteres e
internacionalizar nuestros programas.
Las clases base de las que heredan todas las clases que proveen soporte para enviar y recibir
streams de caracteres son Reader y Writer. Veamos un ejemplo en el cual leemos caracteres
desde un archivo para escribirlos en otro. Los nombres de ambos archivos se especifi can como
argumentos en línea de comandos.
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
int c = fr.read();
while( c != -1 ) {
fw.write(c);
c = fr.read();
fw.close();
fr.close();
Como podemos ver, leer y escribir bytes o caracteres a través de un stream es prácticamente
lo mismo. El método read de la clase FileReader retorna un valor de tipo int. La diferencia
entre este int y el int que retorna el método read de la clase FileInputStream es que el primero
codifi ca 16 bits (un char) mientras que el segundo codifi ca 8 (un byte).
Streams bufferizados
Java provee clases que permiten almacenar temporalmente en memoria los datos que
queremos enviar o leer a través de un stream. El uso de estas clases incrementa el rendimiento
de nuestro programa porque ayuda a minimizar el overhead generado por el uso de recursos
como accesos a disco, actividad de red, etcétera. El área de memoria temporal en el que se
almacena la información que llega o que se envía se llama buffer. Un programa puede escribir
en un buffer pero físicamente el stream fl uirá cuando el buffer esté lleno. Análogamente, un
programa puede leer datos desde un buffer, pero físicamente se leerá el stream cuando el
buffer esté vacío. Las clases que permiten bufferizar streams son BufferedReader,
BufferedWriter, BufferedInputStream y BufferedOutputStream.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
int c = br.read();
while( c != -1 ) {
bw.write(c);
c = br.read();
bw.close();
br.close();
En este caso, veremos un ejemplo en el cual escribimos en un archivo los datos que ingresa el
usuario por teclado. El nombre del archivo debe especifi carse como argumento en la línea de
comandos.
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
int i = scanner.nextInt();
while( i>0 ) {
dos.writeInt(i);
i = scanner.nextInt();
dos.close();
bos.close();
El archivo de salida tendrá n*4 bytes siendo n la cantidad de valores enteros que haya
ingresado el usuario. Cada valor se almacenará en el archivo con el mismo formato que Java
utiliza para codifi car los enteros (usando 4 bytes). Por este motivo, si intentamos abrir el
archivo con algún editor de texto solo veremos símbolos y caracteres raros. No veremos los
valores numéricos que el programa guardó. A continuación, veremos el programa inverso que
lee el archivo generado recientemente y muestra en la pantalla cada uno de los enteros leídos.
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
try {
int i = dis.readInt();
while( true )
System.out.println(i);
i = dis.readInt();
} catch(EOFException ex)
dis.close();
bis.close(); }
Streams de objetos
(ObjectInputStream y ObjectOutputStream)
package libro.cap13;
import java.io.Serializable;
{ edad = e;
nombre = n;
dni = d;
}
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
oos.writeObject(new Persona(10,"Pablo","23.112.223"));
oos.writeObject(new Persona(20,"Pedro","35.213.321"));
oos.writeObject(new Persona(30,"Juan","17.554.843"));
oos.close();
bos.close(); } }
Ahora veamos el programa inverso que leerá los objetos almacenados en el archivo
personas.dat y los mostrará en la pantalla. El método readObject arrojará una excepción de
tipo EOFException cuando encuentre el eof.