Reescribamos el ejemplo de Escribir Nuestros Propios Streams Filtrados para que funcione sobre RandomAccessFiles. Como RandomAccessFile implementa los interfaces DataInput y DataOutput, un beneficio lateral es que los streams filtrados tambi�n funcionan con otros streams DataInput y DataOutput incluidos algunos streams de acceso secuencial como DataInputStream y DataOutputStream.
El ejemplo CheckedIOTest de Escribir Nuestros Propios Streams Filtrados implementa dos streams filtrados, CheckedInputStream y CheckedOutputStream, que calculan un checksum de los datos que son le�dos o escritos en el stream.
El nuevo ejemplo, CheckedDataOutput es una re-escritura de CheckedOutputStream--calcula un checksum para los datos escritos en el stream-- pero opera sobre objetos DataOutput en lugar de sobre objetos OutputStream. De forma similar CheckedDataInput modifica CheckedInputStream para que ahora funciona sobre objetos DataInput en lugar de objetos InputStream.
�CheckedDataOutput contra CheckedOutputStream
Echemos un vistazo a las diferencias entre CheckedDataOutput y CheckedOutputStream.
La primera diferencia es que CheckedDataOutput no desciende de FilterOutputStream. En su lugar, implementa el interface DataOutput.
public class CheckedDataOutput implements DataOutput
|
Nota:
Para mantener el ejemplo sencillo, la clase CheckedDataOutput realmente proporcionada en esta secci�n no est� declarada para implementar DataOutput, porque el interface DataOutput especifica demasiados m�todos. Sin embargo, la clase CheckedDataOutput proporcionada en el ejemplo implementa varios m�todos de DataOutput para ilustrar como deber�an funcionar. |
Luego, CheckedDataOutput declara una variable privada para contener un objeto DataOutput.
private DataOutput out;
Este es el objeto en el se escribir�n los datos.
El constructor para CheckedDataOutput es diferente del constructor de CheckedOutputStream: CheckedDataOutput se crea sobre un objeto DataOutput en vez sobre un objeto OutputStream.
public CheckedDataOutput(DataOutput out, Checksum cksum) {
this.cksum = cksum;
this.out = out;
}
Este constructor no llama a super(out) como hac�a el constructor de CheckedOutputStream. Esto es porque CheckedDataOutput desciende de Object en vez de la clase stream.
Aqu� est�n las �nicas modificaciones echas a CheckedOutputStream para crear un filtro que funcione sobre objetos DataOutput.
�CheckedDataInput contra CheckedInputStream
CheckedDataInput requiere los mismos cambios que CheckedDataOuput.
- CheckedDataInput no desciende de FilterInputStream pero implementa el interface DataInput.
Nota: Para mantener el ejemplo sencillo, la clase CheckedDataInput realmente proporcionada en esta secci�n no est� declarada para implementar DataInput, porque el interface DataInput especifica demasiados m�todos. Sin embargo, la clase CheckedDataInput proporcionada en el ejemplo implementa varios m�todos de DataInput para ilustrar como deber�an funcionar.
- CheckedDataInput declara una variable privada para contener un objeto DataInput que lo envuelve.
- El constructor de CheckedDataInput requiere un objeto DataInput en vez de un objeto InputStream.
Adem�s de estos cambios, el m�todo read tambi�n se ha modificado. El CheckedInputStream del ejemplo original implementa dos m�todos read, uno para leer un s�lo byte y otro para leer un array de bytes. El interface DataInput teine m�todos que implementan la misma funcionalidad, pero tienen diferentes nombres y firmas de m�todos. As� el m�todo read de la clase CheckedDataInput tiene nuevos nombres y firmas de m�todos.
public byte readByte() throws IOException {
byte b = in.readByte();
cksum.update(b);
return b;
}
public void readFully(byte[] b) throws IOException {
in.readFully(b, 0, b.length);
cksum.update(b, 0, b.length);
}
public void readFully(byte[] b, int off, int len)
throws IOException
{
in.readFully(b, off, len);
cksum.update(b, off, len);
}
�Los Programas Principales
Finalmente, este ejemplo tiene dos programas principales para probar los nuevos filtros. CheckedDITest, que ejecuta el filtro sobre ficheros de acceso secuencial (objetos DataInputStream y DataOutputStream), y CheckedRAFTest, que ejecuta los filtros sobre ficheros de acceso aleatorio (objetos RandomAccessFiles).
Estos dos programas se diferencian s�lo en el tipo del objeto que abren para el filtro. CheckedDITest crea un DataInputStream y un DataOutputStream y usa el filtro checksum sobre ellos, como en el siguiente c�digo:
cis = new CheckedDataInput(
new DataInputStream(new FileInputStream("farrago.txt")),
inChecker);
cos = new CheckedDataOutput(
new DataOutputStream(new FileOutputStream("outagain.txt")),
outChecker);
CheckedRAFTest crea dos RandomAccessFiles, uno para leer y uno para escribir, y usa el filtro checksum sobre ellos.
cis = new CheckedDataInput(
new RandomAccessFile("farrago.txt", "r"),
inChecker);
cos = new CheckedDataOutput(
new RandomAccessFile("outagain.txt", "rw"),
outChecker);
Cuando ejecutemos cualquiera de estos programas deber�amos ver la siguiente salida:
Input stream check sum: 736868089 Output stream check sum: 736868089