La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Introducción Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y.

Presentaciones similares


Presentación del tema: "Introducción Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y."— Transcripción de la presentación:

1

2 Introducción Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y escritura en NIO Entendiendo el comportamiento de un buffer Mas sobre buffers File lockings Networking y E/S asincrónica Character sets

3 La API NIO (java.nio) es introducida en Java 1.4 Suplementa las facilidades de la API IO (java.io) Provee nuevas características y mejora la performance en las áreas de: Manejo de buffers Networking escalable Entrada/Salida de archivos Soporte de character sets Expresiones regulares

4 Buffers para datos de tipos primitivos Codificadores y decodificadores de Character-sets Facilidad de pattern-matching basada en expresiones regulares estilo Perl Interface de archivo que soporta bloqueos y mapeo de memoria Facilidad de entrada salida multiplexada, no bloqueante, para implementar servidores escalables

5 Única forma de manipular E/S era mediante la abstracción de flujos (Streams), y sus versiones especializadas para caracteres Unicode (Readers y Writers) Movimientos de bytes simples, uno a la vez, a través de objetos Stream Un flujo de entrada InputStream produce un byte de datos Un flujo de salida OutputStream consume un byte de datos

6 Ejemplo 1 Cliente/Servidor Operaciones bloqueantes Ejemplo 2 Usar Threads para permitir escalar Problema: Thread overhead

7 Implementación de E/S de alta velocidad sin necesidad de escribir código nativo NIO traslada la mayoría de las operaciones pesadas (manejo de buffers) de E/S al sistema operativo IO ha sido reimplementada utilizando NIO

8 Criterio principal en el diseño de la API NIO Las aplicaciones servidor en un sistema distribuido deben manejar múltiples clientes enviando pedidos de servicio concurrentes Previo a la invocación de un servicio, el servidor debe despachar cada pedido entrante al servicio correspondiente (en forma concurrente) El patrón Reactor resuelve esta funcionalidad Principales funcionalidades del patrón Reactor Despachar eventos a manejadores de eventos

9

10 Objetos centrales de la API Usados prácticamente en todas las operaciones de E/S Canales (Channel) Análogos a Streams en el paquete IO Todos los datos deben pasar por un canal Buffers

11 Un Buffer es un objeto contenedor de datos sobre el que se escriben, o del que se leen, datos En NIO todos los datos son manejados con Buffers Esencialmente es una secuencia (generalmente de bytes, pero puede ser de otro tipo), que provee acceso estructurado a los datos

12 Un Canal es un objeto del que se pueden leer (o al que se pueden escribir) datos. Un canal es similar a un stream. Todos los datos son manejados mediante Buffers. Nunca se escribe/lee un byte directamente en/de el canal Los canales son bidireccionales. Los streams son unidireccionales Tipos de canales Un stream debe ser subclase o bien de InputStream o bien de OutputStream Un Canal puede ser abierto para lectura, escritura o ambas

13 Lectura de un canal: Creo un buffer Solicito al canal que coloque datos en él Escritura sobre un canal: Creo un buffer Lleno el buffer con datos Solicito al canal que escriba los datos contenidos en el buffer

14 Estado Cambian con cada lectura/escritura Permiten que el buffer maneje sus propios recursos Accessors get() - Obtiene datos del buffer put() – Escribe datos en el buffer

15 Creo un buffer de 8 slots Posiciones válidas 0 a 7 Position = 0 Limit = Capacity = 8

16 Leo de un canal (por ejemplo 3 bytes) Position = 3 Limit = Capacity = 8

17 Segunda lectura (por ejemplo 2 bytes) Position = 5 Limit = Capacity = 8

18 Ejecuto flip() para poder leer del buffer 1.Limit = Position = 5 2.Position = 0 3.Capacity = 8

19 Leo datos del buffer (escribo en un canal) Por ejemplo 4 bytes Limit = 5 Position = 4

20 Leo datos del buffer (escribo en un canal) Por ejemplo 1 byte (lo que resta) Limit = 5 Position = 5

21 Invoco clear Position = 0 Limit = Capacity = 8

22 Accessors en ByteBuffer byte get() ByteBuffer get(byte dst []) ByteBuffer get(byte dst [], int offset, int lenght) byte get(int index) Los tres primeros son relativos (a position) y modifican el estado (position) El cuarto es absoluto y no afecta el estado

23 put() en ByteBuffer ByteBuffer put(byte b) ByteBuffer put(byte src []) ByteBuffer put(byte src [], int offset, int lenght) ByteBuffer put(ByteBuffer src) ByteBuffer put(int index, byte b) Los cuatro primeros son relativos (a position) y modifican el estado (position) El quinto es absoluto y no afecta el estado

24 get() y put() tipados getByte() getChar() getShort() getInt() getLong() getFloat() getDouble() putByte() putChar() putShort() putInt() putLong() putFloat() putDouble()

25 Asignación de espacio Previo a utilizar un buffer es necesario reservar el espacio para su contenido Método estático allocate() crea el array interno ByteBuffer buffer = ByteBuffer.allocate(1024); Wrapping Es posible convertir un array existente en un Buffer byte[] arr = new byte[1024]; ByteBuffer buffer = ByteBuffer.wrap(arr); Cuidado: los datos pueden ser accedidos desde arr !!!

26 Slicing El método slice() crea una especie de sub buffer de un buffer Datos compartidos con una porción del buffer origen ByteBuffer buffer = ByteBuffer.allocate( 10 ); for (int i=0; i

27 Buffers de solo lectura Usar el método asReadOnlyBuffer() para obtener una copia de solo lectura del buffer Comparte datos con el buffer original Un buffer de solo lectura no puede convertirse en un buffer de lectura/escritura

28 Scattering/Gattering Lectura/Escritura de un canal usando múltiples buffers Útil para separar porciones de datos diferentes (ejemplo: secciones de tamaño fijo en un paquete de un protocolo de red) Interfaces: ScatteringByteChannel y GatheringByteChannel

29 No tiene que ver con prevenir cualquier uso de un archivo Permite que distintas partes de la aplicación coordinen los archivos compartidos y la adquisición de locks Se puede bloquear un archivo entero o una parte del mismo

30 A continuación, veremos un ejemplo en el cual se intenta abrir un archivo.txt utilizando los bloqueos de archivos.

31 E/S asincrónica Una invocación a read() sobre un InputStream bloquea el hilo actual hasta que hayan datos disponibles E/S asincrónica no es bloqueante La aplicación se registra por un evento de E/S particular (disponibilidad de nuevos datos, conexiones de socket, etc.) y el sistema notifica la llegada del evento Es posible escuchar por eventos en un número arbitrario de canales sin necesidad de polling o hilos extra

32 Selectores Es el objeto sobre el cual registrarse por eventos de E/S Notifica la ocurrencia de estos eventos Luego es necesario registrar los canales sobre el selector para notificarnos de la ocurrencia de eventos

33 Abriendo un ServerSocketChannel Objeto que recibe las solicitudes de conexiones (uno por cada puerto) El argumento OP_ACCEPT especifica que se va a escuchar por eventos accept (nueva conexión) Cuando un Selector notifica un evento lo hace proveyendo la SelectionKey que corresponde al evento La SelectionKey puede ser usada para desregistrar el canal

34 El loop interno Notificación de eventos int num = selector.select(); Set selectedKeys = selector.selectedKeys(); Iterator it = selectedKeys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey)it.next(); //... deal with I/O event... }

35 Escuchando por nuevas conexiones Consulto el tipo de evento if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { // Accept the new connection //... }

36 Luego de recibido el evento de solicitud de conexión, se acepta mediante la operación no bloqueante accept() ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); SocketChannel sc = ssc.accept();

37 Configuramos en nuevo SocketChannel como no bloqueante Registramos el SocketChannel con el Selector para informarnos de los eventos de llegada de datos (OP_READ) sc.configureBlocking(false); SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ);

38 A continuación, veremos un ejemplo en el cual se establece una conexión. Para ello, se utilizan sockets. En este caso, según el tipo de la key enviada, la conexión será para escribir, leer, conectarse o aceptar conexión.

39 Un Charset es un mapa nominado entre secuencias de caracteres Unicode de 16 bits y secuencias de bytes Permite leer y escribir secuencias de caracteres en la forma mas portable posible Java se basa en Unicode No todo se basa en Unicode Charset permite codificar y decodificar entre distintas representaciones Ejemplo: Unicode ISO

40 Ejemplo Se leen los datos de un archivo de texto (ISO ) en un CharBuffer (usando un CharsetDecoder) Se recodifican en UTF16 y se escriben en un nuevo archivo usando un CharsetEncoder Cualquier implementación de Java debe soportar US-ASCII ISO UTF-8 UTF-16BE UTF-16LE UTF-16

41 A continuación veremos un ejemplo en el cual se quiere convertir bytes ISO en un ByteBuffer, a un string en CharBuffer y viceversa.

42 Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y escritura en NIO Entendiendo el comportamiento de un buffer Mas sobre buffers File lockings Networking y E/S asincrónica Character sets

43 Getting started with New IO (NIO) Greg Travis IBM Developer works i.html i.html Sun New I/O APIs Guide Java NIO Ron Hitchens OReilly ISBN: , 312 pages


Descargar ppt "Introducción Características de la nueva API E/S antes de Java 1.4 ¿Por qué NIO? E/S orientada a bloques El patrón Reactor Canales y Buffers Lectura y."

Presentaciones similares


Anuncios Google