Sie sind auf Seite 1von 22

Archivos de acceso Aleatorio

IF3000 Programación II
M.c.i. Wendy Ramírez
M.c.i. Alejandro Ulate
Repaso Archivos

El objeto File es inmutable, una vez creado no puede


hacer referencia a otro fichero.

Atributo Separador: Separador de directorios:


En Linux/Unix: se utiliza /
En Windows, se utiliza \\ (realmente es \ pero para
ponerlo dentro de una cadena hay que duplicarlo)

Los Streams se abren automáticamente al crearlos,


pero es necesario cerrarlos explícitamente llamando
al método close() cuando se dejan de usar.
Archivos Aleatorios

Se utiliza la clase RandomAccessFile


• No está basada en el concepto de flujos o Streams.
• No deriva de InputStream/OutputStream ni Reader/Writer, sino
directamente de Object.
• Permite leer y escribir sobre el fichero, no es necesario dos clases
diferentes.
• Necesario especificar el modo de acceso al construir un objeto de esta
clase: sólo lectura o lectura/escritura.
• Dispone de métodos específicos de desplazamiento como seek(long
posicion) o skipBytes(int desplazamiento) para poder moverse de un
registro a otro del fichero, o posicionarse directamente en una posición
concreta del fichero.
• Los datos se guardan en forma de bytes.
Archivos Aleatorios (cont.)

Constructores:
• RandomAccessFile(File f, String modoAcceso)
• RandomAccessFile(String nombreArchivo, String modoAcceso)
modoAcceso puede ser: “r” (sólo lectura) o “rw” (lectura y
escritura).
Métodos:
• void seek(long posicion): Sitúa el puntero de lectura/escritura
en la posición indicada, desde el principio del fichero.
• long getFilePointer(): Devuelve la posición actual del puntero
de lectura/escritura.
• int skipBytes(int desplazamiento): Desplaza el puntero desde
la posición actual, el número de bytes indicado por
desplazamiento
• long length(): Devuelve la longitud o tamaño del fichero en
bytes
Ejemplo escritura/lectura
Serialización

Serialización: Posibilidad de escribir/leer Objetos java en Streams o


Archivos.
La serialización de un objeto consiste en generar una secuencia
de bytes lista para su almacenamiento o transmisión. Después,
mediante la deserialización, el estado original del objeto se puede
reconstruir.

Para poder serializar un objeto en java deben cumplirse los


siguientes requisitos:
• Debe implementar la interfaz Serializable (que lo único que hace es
marcar el objeto como serializable, sin que tengamos que
implementar ningún método).
• Todos los objetos incluidos en él tienen que implementar la interfaz
Serializable.
• Todos los tipos primitivos en Java son serializables por defecto
(igual que los arrays y otros muchos tipos estándar).
Serialización (cont.)
Serialización (cont.)
import java.io.*;
public class ContactoOutput
{
private FileOutputStream file;
private ObjectOutputStream output;
// Abrir el fichero
public void abrir() throws IOException
{
file = new FileOutputStream( "clientes.ser" );
output = new ObjectOutputStream(file);
}
// Cerrar el fichero
public void cerrar() throws IOException
{
if (output!=null)
output.close();
}
// Escribir en el fichero
public void escribir (Contacto contacto) throws IOException
{
if (output!=null)
output.writeObject(contacto);
}
}
Uso

Escritura de datos
ContactoOutput salida;
salida = new ContactoOutput();
salida.abrir();
salida.escribir( contacto1 );
salida.escribir( contacto2 );
salida.cerrar();
Uso

Lectura de datos
Contacto contacto;
ContactoInput entrada;
entrada = new ContactoInput();
entrada.abrir();
do {
contacto = entrada.leer();
System.out.println(contacto);
} while (contacto!=null);
entrada.cerrar();

NOTA: El fichero con los objetos serializados contactos.ser


almacena los datos en un formato propio de Java, por lo que no se
puede leer fácilmente con un simple editor de texto (ni editar).
Deserialización
import java.io.*;
public class ContactoInput
{
private FileInputStream file;
private ObjectInputStream input;
public void abrir() throws IOException
{
file = new FileInputStream( "clientes.ser" );
input = new ObjectInputStream (file);
}
public void cerrar() throws IOException
{
if (input!=null )
input.close();
}
public Contacto leer () throws IOException, ClassNotFoundException
{
Contacto contacto = null;
if (input!=null) {
try {
contacto = (Contacto) input.readObject();
} catch (EOFException eof) {
// Fin del fichero
}
}
return contacto;
}
}
Trabajo con Objetos

En este tipo de aplicaciones, se ha de acceder a un registro


concreto dentro de un fichero, por lo que los registros deben ser de
tamaño fijo:

Como Java utiliza caracteres UNICODE, cada carácter de una


cadena de caracteres ocupa 16 bits (2 bytes).
La clase RandomAccessFile nos permitirá representar un
fichero de acceso aleatorio para el que nosotros definiremos el
formato de sus registros.
Clase Registro

import java.io.*;
import java.text.DateFormat;
public class Registro extends Contacto
{
public final static int DIM = 364;
// Lectura
public void read (RandomAccessFile file) throws IOException, java.text.ParseException
{
DateFormat df;
setNombre ( readString (file, 32) );
setTelefono ( readString (file, 16) );
setEmail ( readString (file, 32) );
setDireccion ( readString (file, 64) );
df = DateFormat.getDateInstance(DateFormat.LONG);
setNacimiento ( df.parse(readString(file,32)) );
setGrupo(file.readInt());
setDeuda(file.readDouble());
}
Clase Registro (cont.)

private String readString


(RandomAccessFile file, int dim) throws IOException
{
char campo[] = new char[dim];
for (int i=0; i<dim; i++)
campo[i] = file.readChar();
return new String(campo).replace('\0',' ');
}
Clase Registro (cont.)

// Escritura
public void write (RandomAccessFile file) throws IOException
{
DateFormat df;
writeString (file, getNombre(), 32);
writeString (file, getTelefono(), 16);
writeString (file, getEmail(), 32);
writeString (file, getDireccion(), 64);
df = DateFormat.getDateInstance(DateFormat.LONG);
writeString (file, df.format(getNacimiento()), 32);
file.writeInt ( getGrupo() );
file.writeDouble ( getDeuda() );
}
Clase Registro (cont.)

private void writeString


(RandomAccessFile file, String str, int dim) throws IOException
{
StringBuffer buffer = new StringBuffer();
if (str!=null)
buffer.append(str);
buffer.setLength(dim);
file.writeChars(buffer.toString());
}
}
Clase Contactos

import java.io.*;
public class Contactos
{
// Fichero de acceso aleatorio
private RandomAccessFile file;
// Apertura del fichero
public void abrir() throws IOException
{
file = new RandomAccessFile("clientes.dat","rw");
}
// Cierre del fichero
public void cerrar() throws IOException
{
if (file!=null)
file.close();
}
Clase Contactos (cont.)

// Escribir un registro
// en la posición actual del cursor
public void escribir (Registro registro) throws IOException
{
if (file!=null)
registro.write(file);
}

// Escribir un registro en una posición cualquiera


public void escribir (Registro registro, int pos) throws IOException
{
if (file!=null) {
file.seek ( (pos-1)*Registro.DIM );
escribir(registro);
}
}
Clase Contactos (cont.)

// Leer del fichero el registro


// que se encuentra en la posición actual del cursor
public Registro leer ()
{
Registro registro = null;
if (file!=null) {
try {
registro = new Registro();
registro.read(file);
} catch (Exception error) {
registro = null;}
}
return registro;
}
Clase Contactos (cont.)

// Leer del fichero un registro cualquiera


// (el parámetro indica la posición del registro)
public Registro leer (int pos) throws IOException
{
if (file!=null) {
file.seek ( (pos-1)*Registro.DIM );
}
return leer();
}
}
Ejemplos de uso
Registro contacto;
Contactos agenda;
agenda = new Contactos();
Escritura secuencial de datos
agenda.abrir();
agenda.escribir( contacto1 );
agenda.escribir( contacto2 );
...
agenda.cerrar();
Lectura secuencial del fichero
agenda.abrir();
do {
contacto = agenda.leer();
...
} while (contacto!=null);
agenda.cerrar();
Acceso aleatorio a los datos (lectura y actualización)
agenda.abrir();
contacto = agenda.leer(2);
contacto.setNombre("JC");
agenda.escribir(contacto,2);
agenda.cerrar();
Bibliografía

Joyanes, Luis. Fundamentos de Programación, Cuarta


edición, España, Mc Graw - Hill, 2008.
Wu, C. Thomas. Programación en Java, Mexico,
Mc Graw - Hill, 2008.
Deitel y Deitel. ¿Cómo programar en Java?. Séptima
edición, México, Prentice Hall, 2008.
Eric Freeman, Elisabeth Freeman, Bert Bates &
Kathy Sierra: The decorator pattern, extraído de
Head-first Design Patterns, O'Reilly, 2004

Das könnte Ihnen auch gefallen