G.Bordel >Docencia >TAP Técnicas Actuales de Programación (curso 2010-2011)
desprotegido Intro. desprotegido Temario desprotegido Calendario desprotegido RPF desprotegido Recursos protegido Práctica protegido Gest. Alum.
tema_anterior Tema 9: Entrada y salida de datos tema_siguiente
  1. Introducción.
  2. Estructura de clases para E/S.[ejercicios]
  3. E/S de objetos. Serialización.
  4. Creación de nuevas clases de E/S.[ejercicios]

9.4- Creación de nuevas clases de E/S

Es posible generar nuevas clases de entrada salida que se ajusten a nuestras necesidades. Normalmente estas clases serán descendientes de las de tipo filtro. A continuación se muestra esto con un ejemplo (en realidad existen unas clases con este mismo nombre pero con una definición algo diferente en java.util.zip).

Supongamos que tenemos la necesidad de asegurarnos en la medida de lo posible la integridad de los datos que enviamos a la salida y recogemos de la entrada y para ello pretendemos utilizar la tecnica de "Checksum" (consistente, a grandes rasgos, en sumar todos los bytes enviados o recibidos y tener este valor como elemento de comprobación en futuras ocasiones). Para ello lo que haremos será generar unas nuevas clases de entrada y salida que se encarguen de actualizar el checksum en cada escritura y lectura de modo que podamos consultarlo cuando sea preciso mediante un método al efecto. Como Java nos proporciona ya un par de mecanismos de Checksum bajo java.util.zip.Checksum (ADler32 y CRC32), dejaremos que el mecanismo a utilizar sea un parámetro de nuestras nuevas clases.

Veamos en primer lugar la clase para salida de datos. Lo que haremos será reescribir los métodos básicos para incluir la actualización del valor de checksum y escribir un nuevo método que proporcione dicho valor.

1-  import java.io.*;
2-  public class CheckedOutputStream extends FilterOutputStream {
3-  private Checksum cksum; 
4-  
5-  public CheckedOutputStream(OutputStream out, Checksum cksum) {
6-      super(out); this.cksum = cksum;
7-      }
8-  
9-  public void write(byte b) throws IOException {
10-      out.write(b); cksum.update(b);
11-      }
12-  
13-  public void write(byte[] b) throws IOException {
14-      out.write(b, 0, b.length); cksum.update(b, 0, b.length);
15-      }
16-  
17-  public void write(byte[] b, int off, int len) throws IOException {
18-      out.write(b, off, len); cksum.update(b, off, len);
19-      }
20-  
21-  public Checksum getChecksum() {
22-      return cksum;
23-      }
24-  }

En la línea 1 importamos el paquete de biblioteca que incluye las clases de E/S a utilizar. En la 2 declaramos la clase que, como indicabamos extenderá a la de filtrado. Como el método de checksum a aplicar será dado como parámetro al constructor, en la línea 3 situamos un campo para referenciar a dicho método. El constructor se encuentra en las líneas 5 a 7 y tomando como parámetros el stream de salida sobre el que actuar y el método de checksum se limita a llamar al constructor de la clase padre y a guardar la referencia al método de checksum.

Los tres métodos en las lineas 9-11, 13-15 y 17-19 son la reescritura de los métodos básicos de salida utilizandolos en primer lugar para realizar la operación requerida y actualizando el checksum mediante el método update . La primera de las tres funciones actualiza el checksum con una función que admite como parámetro un byte, mientras que las otras dos utilizan una que admite una parte de un array al no existir en java.util.zip.Checksum una que admita un array completo para la segunda de ellas.

Acontinuación podemos ver el código de la correspondiente clase de entrada. La similitud es total a excepción del hecho de que en entrada pueden producirse excepciones por lo que los tres métodos de lectura declaran arrojarlas para, simplemente, desentenderse de ellas y ser equivlentes de este modo a los métodos del InputStream que reescriben. Por otro lado estos métodos devuelven el número de bytes leidos (o el byte leido en el caso sin parámetros) o un valor de -1 si no se ha realizado lectura alguna, siendo este valor el recibido de las rutinas de InputStream, pero además tienen en cuenta que el valor -1 debe prevenir de actualizar el checksum.

1-  import java.io.*;
2-  
3-  public class CheckedInputStream extends FilterInputStream {
4-  private Checksum cksum;
5-  
6-  public CheckedInputStream(InputStream in, Checksum cksum) {
7-      super(in); this.cksum = cksum;
8-      }
9-  
10-  public int read() throws IOException {
11-      int b = in.read();
12-      if (b != -1) {cksum.update(b);}
13-      return b;
14-      }
15-  
16-  public int read(byte[] b) throws IOException {
17-      int len;
18-      len = in.read(b, 0, b.length);
19-      if (len != -1) {cksum.update(b, 0, len);}
20-      return len;
21-      }
22-  
23-  public int read(byte[] b, int off, int len) throws IOException {
24-      len = in.read(b, off, len);
25-      if (len != -1) {cksum.update(b, off, len);}
26-      return len;
27-      }
28-  
29-  public Checksum getChecksum() {
30-      return cksum;
31-      }
32-  }

Siguiente Tema: 10- Hilos


Plataforma de soporte a curso y contenidos (c) German Bordel 2005.