Trabajar con Ficheros de Acceso Aleatorio
Hasta ahora los streams de entrada y salida de esta lección han sido streams de acceso secuecnial--streams cuyo contenido debe ser leído o escrito secuencialmente. A pesar de su increible utilidad, los ficheros de acceso secuencial son una consecuencia de un medio secuecial como una cinta magnética. Los ficheros de acceso aleatorio, por otro lado, permiten acceso no secuencial, o aleatorio, a los contenidos de un fichero.
Pero por qué necesitamos ficheros de acceso aleatorio. Consideremos el formato de archivo conocido como "zip". Los archivos Zip contienen ficheros que normalmente están comprimidos para ahorrar espacio. Los archivos Zip también contienen al final un directorio de entradas que indica donde empiezan los distintos ficheros contenidos enel archivo Zip.
Supongamos que queremos extraer un fichero específico de un archivo Zip. Si usamos un stream de acceso secuencial, tenemos que hacer lo siguiente:
- Abrir el fichero Zip.
- Buscar a través del fichero Zip hasta localizar el fichero que queremos extraer.
- Extraer el fichero.
- Cerrar el archivo Zip.
Como media, usando este algoritmo, tendríamos que leer la mitad del archivo Zip antes de encontrar el fichero que queremos extraer. Podemos extraer el mismo fichero del archivo Zip de forma más eficiente usando la característica "seek" de un fichero de acceso aleatorio:
- Abrimos el fichero Zip.
- Saltamos al directorio de entradas y localizamos la entrada del fichero que queremos extraer del archivo Zip.
- Saltamos (hacia atrás) dentro del archivo Zip a la posición del fichero a extraer.
- Extraemos el fichero.
- Cerramos el archivo Zip.
Este algoritmo es más eficiente porque sólo tenemos que leer el directorio de entradas y el fichero que queremos extraer.
La clase RandomAccessFile del paquete java.io implementa ficheros de acceso aleatorio.
Al contrario que las clases de streams de entrada y salida del paquete java.io, RandomAccessFile se usa tanto para leer como para escribir. Creamos un objeto RandomAccessFile con diferentes argumentos dependiendo si intentamos leer o escribir.
RandomAccessFile está desconectado de alguna forma de los streams de entrada y salida de java.io--no desciende de InputStream o OutputStream. Esto tiene algunas desventajas en que no se pueden aplicar los mismos filtros para RandomAccessFiles que aplicabamos a los streams. Sin embargo, RandomAccessFile implementa los interfaces DataInput y DataOutput, por eso podemos diseñar un filtro que funcione con DataInput o con DataOutput, funcionará con algunos ficheros de acceso secuencial (lo que implementen DataInput
o DataOutput) así como en cualquier RandomAccessFile.