Vous êtes sur la page 1sur 31

Streams en Java

1
ALGORITMICA II UNMSM

Generalidades
Un Stream es simplemente una fuente o destino de bytes. Los streams ms comunes son los archivos. Tambin pueden ser caracteres de un string o bloque de memoria o bytes de un socket. La idea es que el programador los trate de la misma forma que archivos. En Java se usan diferentes mecanismos para dar formato a datos. Ofrece clases orientada a manejo de bajo nivel y otras de alto nivel. Da gran flexibilidad y hace uso de filtros en cascada para manipular los datos de entrada o salida. En general la flexibilidad en ocasiones resulta ms aparatosa que lo que desearamos.
UNMSM ALGORITMICA II

Jerarqua para flujos de caracteres de Caracteres Clase para lectura


ALGORITMICA II UNMSM

Clase abstracta

Clase para escritura de caracteres

Clase abstracta

PrintWriter

Jerarqua para flujos de bytes


Lectura de bytes
UNMSM ALGORITMICA II

Clase abstracta

Escritura de bytes

Clase abstracta

Clases bases para Salida


La clase OutputStream es una clase abstracta que especifica un nmero de operaciones para escribir un byte, para escribir un arreglo de bytes, y para cerrar el stream. Clases derivadas de sta son FileOutputStream y ByteArrayOutputStream, las cuales son clases concretas (no abstractas). Sus operaciones de write envan bytes a archivo o memoria. Para dar formato a los datos (imprimir nmeros y strings) se dispone de las clases Writers. PrintWriter es una clase de esa jerarqua, la cual recibe en su constructor el objeto con el cual podr escribir (write) los bytes. Ej. FileOutputStream fout = new FileOutputStream(output.dat); PrintWriter pout = new PrintWiter(fout);
UNMSM ALGORITMICA II

Ejemplo: Copia de un archivo


import java.io.*;

FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c;


while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } }

ALGORITMICA II

public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt");

UNMSM

Clases bases para Salida (Buffer) formato podemos disponer de un buffer para mejorar el Adems de
ALGORITMICA II

desempeo de algunos dispositivos de entrada y salida. El incorporar un buffer y con ello crear la cadena es un caso de filtrado, se usa: PrintWriter pout = new PrintWriter( new BufferedOutputStream (new FileOutpurStream(Output.dat)));

PrintWriter

BufferedOutputStream

FileOutputStream

Los filtros se pueden construir usando cualquier combinacin de clases encadenando una despus de la otra. La primera clase es aquella que permite leer o escribir objetos, y la ltima clase de la cadena enva o recibe los bytes. Las clases intermedias pueden hacer el trabajo que necesitemos (buffer, encriptacin etc.)

UNMSM

Clases bases para Salida


Para escribir texto, podemos usar PrintWriter y sus operaciones print o println. PrintWriter out; Employee harry; .... // apertura del PrintWriter entre otras out.println(3.14); out.print(Harry : ); out.print(harry); Cuando se imprimen objetos, se invoca el mtodo toString del objeto. La clase Object implementa este mtodo, el cual imprime la clase del objeto y su direccin. Lo recomendable es re-definir este mtodo para producir un string que tenga ms sentido para la clase especfica.
UNMSM ALGORITMICA II

Clases bases para Entrada y Salida de bytes (no


necesariamente legible por humanos) Para salida binaria, usamos las clases DataInputStream y DataOutputStream. Ellas proveen las siguientes operaciones: DataInputStream DataOutputStream readInt writeInt readShort writeShort readLong writeLong readFloat writeFloat readDouble writeDouble readBoolean writeBoolean readChar writeChar writeChars Ejemplo: DataOutputStream out = new DataOutputStream(new FileOutputStream(output.dat)); out.writeDouble(3.14); out.writeChars(Harry);

ALGORITMICA II

UNMSM

Clases bases para Entrada y Salida de bytes (no


necesariamente legible por humanos)

Una propiedad importante de las operaciones previas es que son independiente del procesador (tamao de datos). Se usa el ordenamiento de la red big-endian. La comunicacin es segura pues la clase se encarga de hacer las conversiones si el procesador es little-endian. Ej. Para guardar un string, primero se puede guardar el tamao y luego los caracteres. String s; .... out.writeInt(s.length()); out.writeChars(s); Para leer el string de vuelta: int len = in.readInt(); StringBuffer b = new StringBuffer(len); for (int i=0; i <len; i++) b.append(in.readChar()); String s = b.toString();

10

ALGORITMICA II

UNMSM

Ejemplos
Lectura de una pgina WEB
URL url = new URL(www.elo.utfsm.cl); InputStream is = url.openStream(); DataInputStream in = new DataInputStream(is); String s; while((s=in.readLine()) != null) { ..... // procesar s ... }
UNMSM

Lectura desde archivo comprimido


ZipInputStream zin =new ZipInputStream(new FileInputStream(employee.zip)); DataInputStream din=DataInputStream(zin);
11

ALGORITMICA II

Archivos
Se dispone de las clase FileInputStream y FileOutputStream. Hay que recordar cerrar el archivo. FileInputStream fin = new FileInputStream (input.dat); ... fin.close(); No hay operaciones muy tiles para trabajar con los archivos en forma directa. Debemos utilizar un adaptador. DataInputStream in = new DataInputStream(fin); Si deseamos hacer ambos lectura y salida de un archivo, se debe usar la clase RandomAccessFile. Esta clase no hereda de InputStream ni OutputStream. Como no hay mltiple herencia en Java, esta clase implementa las interfaces DataInput y DataOutput. Para abrir un archivo random: RandomAccessFile in = new RandomAccessFile(input.dat, r); RandomAccessFile inOut = new RandomAccessFile(input.dat, rw); Los archivos random disponen de funciones para hacer un seek como en C.
UNMSM

12

ALGORITMICA II

String como un Stream


UNMSM

Se emplean las clases ByteArrayOutputStream y ByteArrayInputStream. Para escribir sobre un string usando print().
Date bday = new Date(1975, 6,16); ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintWriter out = new PrintWriter(bout); out.print(Birthday: ); out.println(bday); String b = out.toString();

13

ALGORITMICA II

Lectura de Entradas de Texto


Para escribir o leer dados binarios usamos DataInputStream o DataOutputStream. Para escritura formateada, usamos PrintWriter. Para lectura de texto en alto nivel no tenemos ninguna clase. Debemos hacerlo a mano. Por ejemplo: Para lectura de lneas podemos usar el mtodo readLine de la clase BufferedReader.
BufferedReader in = new BufferedReader(new FileReader(employee.txt); String line; while ((line = in.readLine())!=null) { hacemos algo }
UNMSM

14

ALGORITMICA II

Lectura de Entradas de Texto (cont)


Para leer nmeros, debemos cargar un string y luego convertirlo. Es posible que debamos extraer el dato desde el string para ello utilizamos la clase utilitaria StringTokenizer. Caso simple: String s=in.readLine(); double x=Double.parseDouble(s); .
UNMSM

15

ALGORITMICA II

16

ALGORITMICA II

Persistencia en Java

UNMSM

Persistencia en Java
Un objeto se dice persistente cuando es almacenado en un archivo u otro medio permanente. Un programa puede grabar objetos persistentes y luego recuperarlos en un tiempo posterior. A diferencia de C++ que slo soporta persistencia a travs de bibliotecas propietarias por lo cual su portabilidad y generalidad es limitada, Java se provee un mecanismo de serializacin para almacenar objetos en disco. La serializacin se obtiene llamando al mtodo writeObject de la clase ObjectOutputStream para grabar el objeto, para recuperarlo llamamos al mtodo readObject de la clase ObjectInputStream. La serializacin adems de persistencia, se puede usar para transferir objetos desde una mquina a otra a travs de un socket .
UNMSM

17

ALGORITMICA II

Interfaz Serializable
Slo objetos que implementen la interfaz Serializable pueden ser escritos a stream. La clase de cada objeto es codificada incluyendo el nombre de la clase y la firma de la clase (su prototipo) los valores de los sus campos y arreglos, y la clausura de cualquier otro objeto referenciado desde el objeto inicial. Para hacer que un objeto sea serializable, slo debemos declarar que implementa la interfaz serializable. Nada ms. No hay ntodos que debamos definir. Por razones de seguridad las clases no son serializable por defecto. Hay que tener claro el orden y tipo de los objetos almacenados en disco para recuperarlos en el mismo orden.
UNMSM

18

ALGORITMICA II

Ejemplo: Empleados serializables


Class Employee implements Seralizable {....} Employee staff = new Employee[3]; .... out.writeObject(staff); Luego podemos recuperar el objeto haciendo: Employee[] newStaff=(Employee[])in.readObject(); Slo objetos pueden ser serializados con writeObject().
UNMSM

19

ALGORITMICA II

Tratamiento de referencia a objetos


Mltiples referencias a un nico objeto son codificadas usando un mecanismo de referencias compartidas de modo que el grafo de objetos puede ser restaurado con la misma forma original. Los mtodos writeObject y readObject se encargan de crear y almacenar un nmero de serie para cada objeto. De este modo objetos ya almacenados no son grabados nuevamente. Supongamos que dada mnager tiene una secretaria. Dos mnager podran compartir la secretaria, en este caso tendriamos algo como:

staff

Employee Name=Eugenia Manager

Si grabamos staff, no queremos tres secretarias luego sino algo equivalente a esta vista en memoria.

Secretary=
Manager Secretary= 20

ALGORITMICA II

UNMSM

Tratamiento de referencia a objetos


Para ello Java utiliza el siguiente algoritmo para serializar (poner nmero de series). A todos los objetos grabados a discos se les asigna un nmero de serie. Antes de grabar un objeto a disco se ve si ya ha sido grabado. Si ya ha sido grabado, se graba lo mismo que el objeto con nmero de series xxx En disco: Sino, se almacena el objeto. Employee name=Eugenia Manager secretary= Manager
UNMSM

Serial number=1 type=Employee name=Eugenia


Serial number=2 type=Manager secretary=objeto 1 Serial number=3 type=Manager secretary=objeto 1

21

secretary=

ALGORITMICA II

Mezcla de objetos serializables y datos bsicos


Podemos hacerlo por medio de los mtodos writeInt, readInt, etc dado que ObjectOutputStream implementa la interfaz DataOutput. Anlogo para la entrada. De datos. Ejemplo: para escribir un objeto, FileOutputStream ostream = new FileOutputStream("t.tmp"); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeInt(12345); p.writeObject("Today"); p.writeObject(new Date()); p.flush(); ostream.close(); La lectura se hace en forma anloga. FileInputStream istream = new FileInputStream("t.tmp"); ObjectInputStream p = new ObjectInputStream(istream); int i = p.readInt(); String today = (String)p.readObject(); Date date = (Date)p.readObject(); istream.close();

22

ALGORITMICA II

UNMSM

Cuando hay objetos no serializables


Clases que requieren manejos especiales durante el proceso de serializacin o deserializacin deben implementar los mtodos:
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException; private void writeObject(java.io.ObjectOutputStream stream) throws IOException
UNMSM

Se aplica en casos que tengamos objetos que no sean serializables (aquellos que tienen algn dato no serializable) Por ejemplo Point2D.Double no es serializable en Java. Para que no reclame el compilador, definimos nuestro dato Point2D.Double como transiente (transient) y luego definimos los mtodos indicados.

23

ALGORITMICA II

Cuando hay objetos no serializables


Ejemplo: public class LabelPoint {.... Private String label; private transient Point2D.Double point; } Luego implementamos: private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeDouble(point.getX()); out.writeDouble(point.getY()); } private void readObject(ObjectInutStream in) throws IOException { in.defaultReadObject(); double x=in.readDouble(); double y=in.writeDouble(); point =new Point2D.Double(x,y); }
UNMSM

24

ALGORITMICA II

Tpicos Usos de los Streams (lectura por lneas)


public static void main(String[] args) throws IOException { // 1a. Se lee un file lnea a lnea BufferedReader in = new BufferedReader( new FileReader("IOStreamDemo.java")); String s, s2 = new String(); while((s = in.readLine())!= null) s2 += s + "\n"; in.close(); // 1b. Se lee una lnea por teclado BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Enter a line:"); System.out.println(stdin.readLine()); }

25

Parsing de tipos bsicos


String linea; int a; BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Enter a line:"); linea = stdin.readLine(); a = Integer.parseInt(linea); System.out.println(a); Tambin estn disponibles: parseDouble(), parseLong()

26

Tpicos Usos de los Streams (escritura por lneas)


// throws IOException String []s = {hola, que, tal}; // Se inicializa s PrintWriter out1 = new PrintWriter( new BufferedWriter( new FileWriter("IODemo.out"))); int lineCount = 1; for (int i=0; i<s.length(); i++) out1.println(lineCount++ + ": " + s[i]); out1.close();

27

Tpicos Usos de los Streams (escritura de tipos bsicos)


// throws IOException

DataOutputStream out2 = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("Data.txt")));

out2.writeDouble(3.14159); out2.writeBytes("That was pi\n); out2.writeChars( "That was pi\n); out2.writeDouble(1.41413); out2.writeUTF("Square root of 2"); out2.close();

28

Tpicos Usos de los Streams (lectura de tipos bsicos)


// throws IOException DataInputStream in5 = new DataInputStream( new BufferedInputStream( new FileInputStream("Data.txt"))); System.out.println(in5.readDouble()); System.out.println(in5.readLine()); // deprecated System.out.println(in5.readDouble()); System.out.println(in5.readUTF());

29

Tpicos Usos de los Streams (files de acceso aleatorio)


// throws IOException // acceso de lectura/escritura RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw"); for(int i = 0; i < 10; i++) rf.writeDouble(i*1.00); rf.close(); rf = new RandomAccessFile("rtest.dat", "rw"); rf.seek(5*8); // salta 5 doubles (8 bytes cada uno) rf.writeDouble(47.00); // modifica el sexto double rf.close(); // acceso de slo lectura rf = new RandomAccessFile("rtest.dat", "r"); for(int i = 0; i < 10; i++) System.out.println( "Value " + i + ": " + rf.readDouble()); rf.close();

30

Tpicos Usos de los Streams (Object Stream)


Java permite guardar objetos en ficheros, pero esos objetos deben implementar la interfaz Serializable:
public class MySerializableClass implements Serializable { ... }

// throws IOException FileOutputStream out = new FileOutputStream("theTime.dat"); ObjectOutputStream s = new ObjectOutputStream(out); s.writeObject("Today"); s.writeObject(new Date(1,1,2006)); s.close(); // throws IOException y ClassNotFoundException FileInputStream in = new FileInputStream("theTime.dat"); ObjectInputStream s = new ObjectInputStream(in); String today = (String)s.readObject(); Date date = (Date)s.readObject(); s.close();

31

Ejemplo:

Vous aimerez peut-être aussi