archivos aleatorios

22
Archivos de acceso Aleatorio Archivos de acceso Aleatorio IF3000 Programación II M.c.i. Wendy Ramírez M.c.i. Alejandro Ulate

Upload: hila3010

Post on 14-Oct-2014

510 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Archivos Aleatorios

Archivos de acceso AleatorioArchivos de acceso Aleatorio

IF3000 Programación II

M.c.i. Wendy Ramírez

M.c.i. Alejandro Ulate

Page 2: Archivos Aleatorios

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.

Page 3: Archivos Aleatorios

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(longposicion) 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.

Page 4: Archivos Aleatorios

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

Hilary
Nota adhesiva
lee o escribe solo un byte
Page 5: Archivos Aleatorios

Ejemplo escritura/lectura

Page 6: Archivos Aleatorios

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).

Page 7: Archivos Aleatorios

Serialización (cont.)

Page 8: Archivos Aleatorios

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);

}

}

Page 9: Archivos Aleatorios

Uso

Escritura de datos

ContactoOutput salida;

salida = new ContactoOutput();

salida.abrir();

salida.escribir( contacto1 );

salida.escribir( contacto2 );

salida.cerrar();

Page 10: Archivos Aleatorios

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.seralmacena 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).

Page 11: Archivos Aleatorios

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;

}

}

Page 12: Archivos Aleatorios

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.

Page 13: Archivos Aleatorios

Clase Registro

import java.io.*;

import java.text.DateFormat;

public class Registro extendsContacto

{

public final static int DIM = 364;

// Lectura

public void read (RandomAccessFile file) throws IOException, java.text.ParseException

{

DateFormatdf;

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());

}

Page 14: Archivos Aleatorios

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',' ');

}

Page 15: Archivos Aleatorios

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() );

}

Page 16: Archivos Aleatorios

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());

}

}

Page 17: Archivos Aleatorios

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();

}

Page 18: Archivos Aleatorios

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);

}

}

Page 19: Archivos Aleatorios

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;

}

Page 20: Archivos Aleatorios

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();

}

}

Page 21: Archivos Aleatorios

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();

Page 22: Archivos Aleatorios

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