Programacin Orientada a Objetos Anexo 5 Streams Universidad
Programación Orientada a Objetos Anexo 5 Streams Universidad de Chile Departamento de Ciencias de la Computación Profesor: Juan Claudio Navarro jnavarro@dcc. uchile. cl, juancla. navarro@gmail. com
Temario n n n Streams El package java. io Streams de bytes y de caracteres Streams de bajo y alto nivel Leyendo y escribiendo Sockets 2
Streams n Los Streams son interfaces que permiten ver de una manera común los diferentes elementos de entrada / salida (archivos, teclado/pantalla, sockets, etc. ) Un stream de entrada: n Un stream de salida: n 3
El Package java. io n Las clases de entrada / salida del paquete java. io: n n n ocultan la complejidad de las operaciones de bajo nivel aíslan al programador de los detalles específicos del sistema operativo proveen una manera consistente de representar la entrada / salida 4
El Package java. io n Las clases de streams del paquete java. io se encuentran divididas en 4 jerarquías de clases, dependiendo de si son de entrada o salida, y del tipo de datos sobre el que operan (bytes o caracteres) Lectura Escritura Operan sobre bytes Input. Stream Output. Stream Operan sobre caracteres Reader Writer 5
Streams Byte v/s Character Streams de Bytes n n Métodos operan sobre (arreglos de) bytes Contiene bytes de 8 -bit Implementado por clases Input. Stream y Output. Stream No manejan buffers Streams de Caracteres n n Métodos operan sobre (arreglos de) caracteres Contiene caracteres Unicode de 16 -bit Implementado por clases Reader y Writer Manejan buffers 6
Reader y Input. Stream n Clases abstractas para leer caracteres y bytes n n n Métodos básicos Reader: Reader n n Reader permite leer streams de caracteres Input. Stream permite leer streams de bytes int read() int read(char[] cbuf) abstract int read(char[] cbuf, int off, int len) Métodos básicos Input. Stream: Input. Stream n n n abstract int read() int read(byte[] bbuf, int off, int len) 7
Writer y Output. Stream n Clases abstractas para escribir caracteres y bytes n n n Métodos básicos Writer: Writer n n Writer permite escribir streams de caracteres Output. Stream permite escribir streams de bytes void write(int c) void write({char[]|String} cbuf) abstract void write({char[]|String} cbuf, int off, int len) Métodos básicos Output. Stream: Output. Stream n n n abstract void write(int b) void write(byte[] bbuf, int off, int len) 8
Streams de Caracteres 9
Streams de Bytes 10
Streams Conectados a Datos n Streams conectados directamente a fuentes o destinos de información (en gris en las jerarquías anteriores) Clases Fuente o destino de datos File. Reader, File. Writer, File. Input. Stream, File. Output. Stream Archivos Piped. Reader, Piped. Writer, Pipied. Input. Stream, Piped. Output. Stream Pipes: un thread lee en un Piped. Reader lo que otro escribe en un Piped. Writer Char. Array. Reader, Char. Array. Writer Arreglos de caracteres String. Reader, String. Writer Strings Byte. Array. Input. Stream, Byte. Array. Output. Stream Arreglos de bytes 11
Encadenamiento de Streams n Streams que operan sobre otros streams, agregando funcionalidad, convirtiendo información, etc. (en blanco en las jerarquías anteriores) Clases Descripción Filter. Reader, Filter. Writer, Filter. Input. Stream, Filter. Output. Stream Clases base para la implementación del patrón de diseño Decorator; los métodos simplemente delegan los requerimientos en el stram “conectado”. Buffered. Reader, Buffered. Writer, Buffered. Input. Stream, Buffered. Output. Stream Manejan buffers. Buffered. Reader agrega además un método read. Line(). Line. Number. Reader, Line. Number. Input. Stream Agregan el método get. Line. Number(). Input. Stream. Reader, Output. Stream. Writer Proveen conversión entre bytes y caracteres. Pushback. Reader, Pushback. Input. Stream Agregan métodos unread(). Sequence. Input. Stream que lee desde una secuencia de objetos Input. Stream. Print. Writer, Print. Stream Agregan métodos para escribir objetos formateadamente. Data. Input. Stream, Data. Output. Stream Proveen métodos para leer y escribir tipos primitivos. Object. Input. Stream, Object. Output. Stream Proveen manejo de serialización. 12
Copiando un Archivo import java. io. *; public class Copy { public static void main(String[] args) throws IOException { File. Reader in = new File. Reader("data. txt"); File. Writer out = new File. Writer("out. txt"); int c; while ((c = in. read()) != -1) { out. write(c); } in. close(); out. close(); } } 13
Encadenando Streams n n Los streams están basados en el patrón de diseño Decorador, que permite agregar responsabilidades a los objetos de manera dinámica y transparente Las clases Filter. Reader, Filter. Writer, Filter. Input. Stream y Filter. Output. Stream son clases base para decoradores: n n n Manejan la referencia al stream “encadenado”, y le delegan los requerimientos Los decoradores concretos agregan o modifican funcionalidad Los decoradores tienen la misma interfaz que los componentes “decorados”, de modo que para el cliente es transparente si está operando con un componente decorado o no 14
Leyendo de un Archivo n El siguiente código permite leer por líneas de un archivo: File. Reader fr = null; Buffered. Reader br = null; try { fr = new File. Reader("/home/archivo. txt"); br = new Buffered. Reader(fr); String s; while ((s = br. read. Line()) != null) {. . . } } finally { if (fr != null) { fr. close(); } } 15
Leyendo del Teclado n El siguiente código permite leer por líneas lo que el usuario escribe en el teclado: Input. Stream. Reader isr = new Input. Stream. Reader(System. in); Buffered. Reader br = new Buffered. Reader(isr); try { System. out. print("Ingrese su nombre: "); String name = br. read. Line( ); System. out. print("Ingrese su dirección: "); String address = br. read. Line( ); } catch (IOException e) { System. out. println("IOException"); } 16
Print. Writer n n Escribe texto y números en formato de texto, en métodos print() y println() El constructor de Print. Writer recibe como parámetro un objeto Output. Stream, Writer, File, o String (el nombre de un archivo) File. Writer fw = new File. Writer("C: /dat/emp. dat"); Print. Writer pw = new Print. Writer(fw); String nombre = "Andrea Ramírez"; double sueldo = 1500000; pw. print(nombre); pw. print(""); pw. print(sueldo); pw. close(); fw. close(); 17
Ejemplo: Encadenando Streams n n El siguiente ejemplo muestra cómo comprimir y encriptar información, escribiendo sobre un archivo: El siguiente código genera la estructura de objetos: n n File. Output. Stream fos = new File. Output. Stream("myfile. out"); Crypt. Output. Stream cos = new Crypt. Output. Stream(fos); GZIPOutput. Stream gos = new GZIPOutput. Stream(cos); Para escribir sobre los streams encadenados se invoca el método write() sobre el objeto más externo: n gos. write('a'); 18
Archivos de Acceso Directo n n n Las clases vistas anteriormente implementan streams de acceso secuencial La clase Random. Access. File implementa archivos de acceso directo, en modalidad lectura y escritura (no está conectada con el modelo de streams) Además de los métodos de lectura y escritura, provee los siguientes métodos adicionales n n n int skip. Bytes(int n) void seek(long pos) long get. File. Pointer() 19
Excepciones n El paquete java. io contiene un conjunto de excepciones, todas derivadas de IOException: n n n EOFException File. Not. Found. Exception Interrupted. IOException Security. Exception 20
Clase File n n Provee una abstracción de los nombres del archivo o directorio en el sistema de archivos Provee métodos útiles para la manipulación de nombres de archivos n n n get. Name() get. Path() last. Modified() mkdir() delete() n n list() exists() is. File() is. Directory() 21
Close n n n Los streams ocupan recursos del sistema operativo Al terminar de usar un stream, hay que cerrarlo utilizando su método close() Al cerrar un archivo se realiza un flush() 22
Sockets n n n La comunicación entre dos procesos remotos en una red TCP/IP se realiza mediante sockets Los sockets soportan comunicación bidireccional: tanto el cliente como el servidor pueden leer y escribir Abrir un socket y enviar data es como abrir un archivo y escribir sobre él 23
El Package java. net n Contiene clases que ocultan la complejidad de: n n n Establecer una conexión en la red Recibir y enviar datos sobre la red Provee la misma interfaz de programación que para archivos 24
Invocando un servicio n Un servidor se identifica por una dirección IP única n n 169. 254. 2. 40 Un servidor puede proveer diferentes servicios, cada uno de los cuales se identifica por una puerta n 169. 254. 2. 40: 80 25
Modelo Cliente / Servidor n El servidor: n n Escucha requerimientos que llegan El cliente: n n Inicia una conexión Entrega (escribe) y/o requiere (lee) información del servidor 26
Programando con Sockets Servidor Cliente 1. Instancia un server socket en un puerto local 2. Acepta conexiones 3. Instancia una conexión de tipo socket a un sistema remoto + puerto en ese socket 4. Conexión establecida 27
Una Aplicación Servidora 1. Instanciar un socket servidor Server. Socket server = new Server. Socket(80); 2. Escuchar (esperar una conexión) Socket s = server. accept(); 3. Obtener input y output streams (si se requiere) Buffered. Reader in = new Buffered. Reader( new Input. Stream. Reader(s. get. Input. Stream())); Buffered. Writer out = new Buffered. Writer( new Output. Stream. Writer(s. get. Output. Stream())); 4. Comunicación String str = in. read. Line(); out. write("mensaje"); 5. Cerrar streams y sockets in. close(); out. close(); server. close(); 28
Una Aplicación Cliente 1. Instanciar un socket cliente Socket s = new Socket("www. miserver. com", 80); 2. Obtener input y output streams (si se requiere) Buffered. Reader in = new Buffered. Reader( new Input. Stream. Reader(s. get. Input. Stream())); Buffered. Writer out = new Buffered. Writer( new Output. Stream. Writer(s. get. Output. Stream())); 3. Comunicación String str = in. read. Line(); out. write("mensaje"); 4. Cerrar streams y sockets in. close(); out. close(); s. close(); 29
Aceptando Múltiples Clientes n Para aceptar múltiples clientes se debe manejar threads (de lo contrario, un cliente no podría conectarse mientras el servidor se encuentre ocupado atendiendo a otro cliente): while (true) { aceptar una conexión; crear un thread para atender al cliente; } n Hoy lo común es utilizar un servidor de aplicaciones en lugar de programar código como el del ejemplo 30
Aceptando Múltiples Clientes import java. net. *; import java. io. *; public class Multi. Server { public static void main(String[] args) throws IOException { Server. Socket server. Socket = new Server. Socket(4444); boolean listening = true; while (listening) { new Multi. Server. Thread(server. Socket. accept()). start(); } server. Socket. close(); } } 31
Aceptando Múltiples Clientes import java. net. *; import java. io. *; public class Multi. Server. Thread extends Thread { private Socket s = null; public Multi. Server. Thread(Socket socket) { this. s = socket; } public void run() { Print. Writer out = new Print. Writer(s. get. Output. Stream(), true); Buffered. Reader in = new Buffered. Reader( new Input. Stream. Reader(s. get. Input. Stream())); . . . } } 32
Resumen n n El paquete java. io tiene dos jerarquías de streams: una para leer/escribir caracteres (clases Reader y Writer), Writer otra para leer/escribir bytes (clases Input. Stream y Output. Stream) Output. Stream Existen streams conectados directamente a fuentes y destinos de información, y streams que se encadenan a otros El paquete java. net permite construir aplicaciones de red basadas en sockets Una vez establecida una comunicación mediante sockets, se generan streams para la comunicación entre el cliente y el servidor 33
- Slides: 33