You are on page 1of 79

ALGORITMICA III

Estructura De
Datos

Docente: Carlos A. Ruiz De La Cruz Melo


Correo: zorroculto69@hotmail.com

PERSISTENCIA
Capacidad para conseguir que los
datos sobrevivan a la ejecucin del
proceso que los creo, de forma que
puedan ser reutilizados en otro
proceso.
Se entiende por persistencia en la
programacin orientada a objetos
como la capacidad que tienen los
objetos de conservar su estado e
identidad entre distintas ejecuciones
del programa que los cre o de otros
programas que accedan a ellos.

Persistencia como
mecanismo
La persistencia no es ni una
capacidad ni una propiedad de la
POO, no tiene nada que ver con el
paradigma en s, solo es el
mecanismo que se usa para persistir
informacin de un determinado tipo
(como puede ser serializar, guardar los
datos en una tabla, en un archivo
plano, etc).

Los objetos para la


persistencia
Una instancia persistente es
aquella cuyos datos perduran a
la ejecucin del proceso que
materializo la instancia.
Una instancia transitoria es
toda instancia cuyos datos
desaparecen cuando finalizan
los procesos que la manipulan

Objetivos de la
persistencia
La
persistencia
permite
al
programador almacenar, transferir y
recuperar el estado de los objetos.
Para esto existen varias tcnicas:
Serializacion
Motores de persistencia
Bases de datos orientadas a objetos

ARCHIVOS/FILAS
Un archivo o fichero de datos es una
coleccin de registros relacionados
entre si con aspectos en comn y
organizados para un propsito
especifico.
Un archivo en una computadora es
una
estructura
diseada
para
contener
datos,
estos
estn
organizados de tal modo que puedan
ser
recuperados
fcilmente,
actualizados
o
borrados
y
almacenados de nuevo en el archivo
con todos los cambios realizados

ARCHIVOS/FILAS
Este tema se centra en el uso de los archivos
como flujos de datos de un programa, tanto de
entrada, para proporcionar los datos necesarios
para realizar la tarea que ejecuta el programa,
como de salida, para almacenar los datos
obtenidos por el programa.
Se puede considerar un flujo como una secuencia
de caracteres.

FLUJOS
Todos los datos fluyen a travs del ordenador desde una entrada hacia
una salida.
Este flujo de datos se denomina tambin stream.
Hay un flujo de entrada (input stream) que manda los datos desde el
exterior (normalmente el teclado) del ordenador, y un flujo de salida
(output stream) que dirige los datos hacia los dispositivos de salida (la
pantalla o un archivo).

El proceso para leer o escribir datos consta de tres pasos


Abrir el flujo de datos
Mientras exista ms informacin (leer o escribir ) los datos
Cerrar el flujo de datos

ORGANIZACION
La organizacin de un archivo define la forma
en la que los registros se disponen sobre el
soporte de almacenamiento, o tambin se
define la organizacin como la forma en que
se estructuran los datos en un archivo. En
general, se consideran tres organizaciones
fundamentales:

Organizacin secuencial
Organizacin directa
Organizacin indexada

APLICACIN
MEMORIA SECUNDARIA

Archivos

DISCO

MEMORIA PRIMARIA

Arreglos
0

Listas

ARCHIVO EN C++ O EN JAVA

micrfono

Para C++ es un dispositivo


externo hacia/desde el cual
puede fluir informacin.

Tipo de archivo que


se usara para filas
secuenciales

impresora

Archivos binarios /
texto
Disco duro

Cinta magntica

ARCHIVO BINARIO/TEXTO
Almacena caracteres ASCII

texto
Almacenamiento
en archivo

Visible por un editor

Almacena en hexadecimal

Binario

No visible por cualquier


editor
Dividido en segmentos

ARCHIVO BINARIO
Estructura de un
archivo binario

REGISTRO 1
REGISTRO 2
:

Dividido en segmentos
de igual tamao

REGISTRO N-1
REGISTRO N

EOF

Marca de fin de archivo


(End of File)

UBICACIN LGICA Y
FSICA
Especificacin ALUMNO
variables
entero : cdigo
cadena: nombre
real : nota
operaciones
significado
Fin_ALUMNO
lgica
0

En C++

fsica
0

56

112

CODIGO NOMBRE

NOTA

90021

Carlos Rojas Snchez

10

89765

Manuel Ventura Daz

11

78560

Ana Alvarado Glvez

15

Suponemos que
cdigo, nombre y
nota suma en total
56 bytes

ACCESO AL DISCO
Para empezar, los discos distribuyen los datos en
dos o tres dimensiones. Las cabezas de
lectura/escritura se mueven a lo largo del radio
del disco, a distancias preestablecidas. Cada una
de esas distancias define una pista
A su vez, cada pista est dividida en partes ms
pequeas, llamadas sectores.
cada disco est compuesto en realidad por varios
discos llamados platos, cada plato tiene dos
caras, y en cada cara se coloca una cabeza de
lectura/escritura.
De modo que para acceder a un dato ser
necesario calcular en qu plato, pista y sector
est almacenado, mover la cabeza a la pista
adecuada y esperar a que el sector pase por
debajo de la cabeza correspondiente al plato
indicado

ACCESO AL DISCO
La unidad mnima que se puede leer o
escribir en un disco es un sector. El tamao
del sector es variable, generalmente son de
512 bytes, pero pueden ser diferentes.
El sistema operativo no trabaja directamente
con sectores, sino con clusters. Cada
cluster tiene un nmero entero de sectores.
Una velocidad de 5400RPM permitir una
transferencia entre 10MB y 16MB por
segundo con los datos que estn en la
parte exterior del cilindro o plato, algo
menos en el interior.
An
cuando
los
microprocesadores
utilizados en los discos duros son
relativamente
poderosos,
las
tareas
asignadas a ellos toman tiempo en llevarse
a cabo. En promedio, este tiempo est en el
rango de los .003 milisegundos.

ORGANIZACIN SECUENCIAL
La Fila secuencial es una estructura
de datos lineal
en la cual los
elementos estn dispuestos uno tras
de otro, de tal modo que en las
operaciones
para manipular los
elementos se respeta la secuencia
de los mismos en la estructura.
Inicio de
archivo

Registro 1
Registro 1
:
Registro 1
:
Registro N-1

fin de
archivo

Registro N

ORGANIZACIN SECUENCIAL
Accesar el prximo registro es trivial.
Para agregar registros a un archivo
secuencial hay dos opciones:
Crear un nuevo archivo.
Agregar al final del archivo.
Para eliminar los registros estos se
pueden marcar (necesidad de un
campo extra) o se debe crear un
nuevo archivo.
Los archivos secuenciales ocupan un
tamao mnimo, o sea, slo el espacio
requerido para el almacenamiento de
los registros.

ORGANIZACIN DIRECTA
Los datos se colocan y se
acceden aleatoriamente
mediante su posicin, es
decir, indicando el lugar
relativo
que
ocupan
dentro del conjunto de
posiciones posibles.
En esta organizacin se
pueden leer y escribir
registros, en cualquier
orden y en cualquier lugar.

ORGANIZACIN DIRECTA
Ventaja
Rapidez de acceso a un
registro cualquiera

Desventajas
Establecer la relacin entre
la posicin que ocupa un
registro y su contenido;
Puede
desaprovecharse
parte del espacio destinado
al archivo

ORGANIZACIN INDEXADA
AREA DE DATOS

Un archivo con esta organizacin


consta de dos reas:
Archivo de ndices
Archivo de datos
AREA DE INDICES
CLAVE
234

CLAVE
010

234

011

234

:
019

234

020

345

021

345

DIRECCION
010
:

345

020

422

030

467

040

678

090

029

345

030

422
:

039

422

DATOS

ORGANIZACIN INDEXADA
01- Razon: A
Fecha: 01/01/11
cod

Descrip

PU

CANT

11

10

18

20

01

Cada objeto de
fila
DATOS
tiene 114 bytes
Fila de DATO

Direccin fsica

Cod.

Descrip.

Pu

cant

01

11

10

01

18

20

01

01

Fila de INDICE
#

Razn

fecha

Dir.
342

01

01/01/11

02

09

4.5

02

02/05/12

342

02

11

15

08

14/07/12

570

570

08

01

010

20/09/12

684

684

010

03

0.5

30

ORGANIZACIN INDEXADA
Ventaja
Rpido acceso, y, adems, el sistema se
encarga de relacionar la posicin de cada
registro con su contenido por medio del
rea de ndices.
Gestiona las reas de ndices y
excedentes.

Desventajas
Necesidad de espacio adicional para el
rea de ndices.
El desaprovechamiento de espacio que
resulta al quedar huecos intermedios libres
despus de sucesivas actualizaciones.

CRITERIOS PARA ELEGIR UN


TIPO DE ORGANIZACIN
Se pueden considerar tres
criterios bsicos:
Rpido Acceso
Economa de
Almacenamiento
Facilidad de Uso

ALGUNAS MEDIDAS DE
RENDIMIENTO
La eleccin de la organizacin
determina el rendimiento relativo del
sistema para cada una de las tres
caractersticas enunciadas:
Almacenamiento requerido por un
registro.
Tiempo de bsqueda de un registro.
Tiempo requerido para leer todo el
archivo.
Tiempo requerido para insertar un
registro.
Tiempo para modificar un registro.

Rpido Acceso
Economa de
Almacenamiento
Facilidad de Uso

PRIMITIVAS
Para F : identificador de fila/archivo/fichero
v : variable del mismo tipo de dato que almacena la fila
inicio( F )

Posiciona el cabezal de lectura de la fila F al


inicio

leer ( F , v )

Coloca en v el contenido de un registro de la


fila F

escribir ( F , v )

Coloca al final de la fila F el contenido de v

ltimo ( F )

Retorna falso si no es final de fila F de lo


contrario retorna verdadero

cerrar ( F )

cierra la fila F

ubicar( F, p )

Se ubica en una posicin p de la fila F

comprimir( F, p )

Escribe una cantidad de objetos P en la fila F

ORGANIZACIN
DIRECTA
Encontrar primero cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0344

Juan

0944

Ana

0723

Jorge

k = i

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0344

Juan

0944

Ana

0723

Jorge

i
k

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0944

Ana

0944

Ana

0723

Jorge

i
k

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0944

Ana

0944

Ana

0723

Jorge

i
k

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0944

Ana

0723

Jorge

0723

Jorge

i
k

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0944

Ana

0723

Jorge

0723

Jorge

i
k

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

ORGANIZACIN
DIRECTA
Se elimino el cdigo

0344
cdigo

nombre

0123

Carlos

0856

Mara

0944

Ana

0723

Jorge

function eliminar(): entero


ALUMNO: a,p
entero: i,
i0
condfalso
salirverdadero
inicio(base)
leer( cod)
leer(base, a)
mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entonces
condverdadero
salirfalso
sino
ii+1
finsi
leer(base, a)
finmientras
ki
salirverdadero
si(cond = verdadero) entonces
mientras(salir=verdadero) hacer
kk+1
ubicar(base,k)
leer(base,p)
si (no ultimo(base)) entonces
ubicar(base, i)
escribir(base, p)
ii+1
sino
cerrar(base)
inicio(base)
comprimir(base, i)
cerrar(base)
salirfalso
finsi
finmientras
sino
cerrar(base)
finsi
fineliminar

PERSISTENCIA EN C++
ARCHIVOS

DOCENTE

ASIGNATURA

Posible en C++

cdigo

nombre

edad

01

Juan

20

04

Mara

18

cdigo

nombre

credito

01112

Estadstica

04023

Matemtica I

08999

Algoritmica

cdigo

nombre edad

categoria

0177

Guerra

20

Auxiliar

0409

Pablo

18

asociado

class PERSONA{
int codigo;
String nombre;
int edad
}

class ASIGNATURA{
int codigo;
String nombre;
int credito
}

No es Posible
en C++

class DOCENTE{
int codigo;
String nombre;
int edad;
String categoria
ASIGNATURA curso[] = new ASIGNATURA[5];

MANEJO DE FILAS EN C
Actualmente existen tres formas para manejar los archivos
en lenguaje C, entre los dos primeros, uno llamado de
primer nivel (tambin llamado secuencial) y otro llamado de
segundo nivel (tambin llamado tipo registro o de alto nivel).
1. En el nivel ms bajo se considera el archivo como un
conjunto de bytes continuos, esto sin tener en cuenta
como se han grabado, un usuario puede leer la
cantidad de bytes que desee no importando la
posicin en la cual se encuentren stos.
2. En el modo de ms alto nivel se puede acceder a uno
o varios registros, es decir, lo que se lee cada vez es
una agrupacin lgica. Las operaciones de primer
nivel, como se las llama a las de nivel ms bajo, son
las ms potentes. Se dice que estas operaciones son
las primitivas del sistema: son las operaciones
bsicas. Las de segundo nivel se construyen a partir
de stas.

INSTRUCCIONES A BAJO NIVEL


La siguiente tabla muestra las instrucciones de primer nivel
para manejo de archivos. Todas estas funciones se
encuentran definidas en el archivo io.h.
read() Lee un buffer de datos
write() Escribe un buffer de datos
open() Abre un archivo en disco
close() Cierra un archivo
lseek() Busca un byte especificado
unlink() Elimina un archivo del directorio

Modos de acceso al archivo:

0x01 Slo Lectura O_RDONLY


0x02 Slo Escritura O_WRONLY
0x04 Lectura/Escritura O_RDWR

INSTRUCCIONES A BAJO NIVEL


Para este ejemplo el archivo
NOMBRE1 debe existir. Si NO
existe la funcin open devuelve -1

#include <stdio.h>
#include <io.h>
void main() {
int f, modo=0x01;
if( (f= open("Nombre1", modo))==-1){
printf("NO se puede abrir ! ");
}
}

Si el archivo NO existe lo
crea. El acceso ser de
lectura-escritura. Todo lo
que escriba en el archivo
borrar la informacin
existente. Si el modo es
O_RDONLY, slo se podr
leer
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
void main(){
int f, modo=0x04; /* Se puede usar O_RDWR en vez de modo */
if( (f= open("Nombre1", modo|O_CREAT))==-1) {
printf("NO se puede abrir ! ");
} else printf(" Archivo Abierto !");
}

INSTRUCCIONES A BAJO NIVEL


Lectura de archivos
int read(int fn, char *buf,int nbytes);
Escritura de archivos
int write(int fn,char *buf,int nbytes);
Posicionamiento de un archivo
long lseek(int fn, long desp1,int modo);
Cierre de archivos
int close(int fn);

Modo

Descripcin

Principio del archivo

Posicin actual en el archivo

Al final del archivo

INSTRUCCIONES DE SEGUNDO
NIVEL
En las instrucciones de segundo nivel los archivos
ya no se designan por un nmero, sino, por un
puntero a una estructura compleja llamada FILE
cuya descripcin se haya en el archivo stdio.h.

Apertura de archivo
FILE *fopen(char *nombrefich, char *modo);
Modo Descripcin
"r"

Para lectura solamente

"w"

Para escritura solamente (si el archivo ya existiera lo


borra)

"a"

Aadir al final de un archivo que ya existe.

"r+"

Actualizar uno que ya existe

INSTRUCCIONES DE SEGUNDO
NIVEL
Lectura de archivo
int fread(char *p,int s,int n, FILE *fp);
Escritura de archivo
fwrite(char *p,int s,int n, FILE *fp);
Cerrar archivo
int fclose(FILE *fp);
Posicionamiento en un archivo
fseek(FILE *fp, long pos, int modo); /* Anloga a lseek */
Condicin de fin de archivo
int feof(FILE *fp);
Posicionamiento al comienzo de un archivo
rewind(FILE *fp);

MANEJO DE FILAS EN C++


En C++, se utilizan streams (flujos)
para gestionar la lectura y escritura de
datos. Ya conocemos dos flujos
estndar: cin y cout.
En definitiva, abrir un fichero significa
definir un stream. Dicho stream permite
la transferencia de datos entre el
programa y el fichero en disco

El buffer es un rea de memoria


situada en la RAM asignada al
programa que abre el archivo

MANEJO DE FILAS EN C++


Toda transferencia de datos entre el programa y
el fichero en disco se realiza a travs del buffer.
El buffer est para dar eficiencia.
Las operaciones de E/S son ms eficientes:

El acceso a la memoria RAM consume


menos tiempo que el acceso a un
dispositivo fsico.
El buffer hace que el nmero de accesos al
fichero fsico sea menor.

El uso del buffer permite realizar operaciones de


entrada salida de forma ms eficiente.

MANEJO DE FILAS EN C++


Para poder manipular archivos, C++ dispone de la
biblioteca estandar fstream (file stream) donde se
encuentran todas las funciones necesarias para abrir y
cerrar archivos, as como para realizar las operaciones
de lectura y escritura de datos en archivos.

C++ provee las siguientes clases para realizar


operaciones de entrada y salida de carcteres hacia o
desde archivos:

ofstream: El flujo para escribir archivos.


ifstream: El flujo para leer archivos.
fstream: Flujo de lectura/escritura sobre archivos

PROGRAMA DE FILAS EN C++


#include <conio.h>
#include <iostream.h>
#include <fstream.h>
class ENTERO{
int num;
public:
void REGISTRAR(int x){
ofstream esc("ejemplo1",ios::app| ios::binary);
if(!esc){ cout<<"archivos on problemas";getch(); }
else{
esc.write(reinterpret_cast<char *>(&x),sizeof(ENTERO));
esc.close();
}
}
void MOSTRAR(){
int y;
ifstream lec("ejemplo1");
if(!lec){
cout<<"archivos con problemas";getch(); }
else {
lec.read(reinterpret_cast<char *>(&y),sizeof(ENTERO));
while(!lec.eof()){
cout<<"\n"<<y;
lec.read(reinterpret_cast<char *>(&y),sizeof(ENTERO));
}
lec.close();
}
}
};

int main(){
char op; int dato;
ENTERO e;
for(;;){
cout<<" \n adicionar <1>";
cout<<" \n Mostrar <2>";
cout<<" \n salir <3>";
op=getch();
switch(op){
case '1':cout<<"\n Ing entero :";cin>>dato;
e.REGISTRAR(dato);break;
case '2':e.MOSTRAR();getch(); break;
case '3':return 0;
}
}
}

PERSISTENCIA EN JAVA
Si bien pudieran encontrarse otros
mecanismos alternativos, es posible que
resultaran problemticos y dieran lugar a
errores, e incluso podran llegar a
complicarse si se necesitara realizar un
seguimiento de la jerarqua de los objetos.
En el caso en el que se debiera escribir
una aplicacin para una gran empresa que
contenga varios miles de objetos y se
tuviera que escribir cdigo para guardar en
un disco y recuperar desde ste los
campos y propiedades para cada objeto, la
serializacin proporcionara el mecanismo
adecuado para conseguir este objetivo con
el mnimo esfuerzo.

PERSISTENCIA EN JAVA
ARCHIVOS

cdigo

nombre

edad

01

Juan

20

04

Mara

18

class PERSONA{
int codigo;
String nombre;
int edad
}

ASIGNATURA

cdigo

DOCENTE

SERIALIZACION

nombre

credito

01112

Estadstica

04023

Matemtica I

08999

Algoritmica

cdigo

nombre edad

categoria

0177

Guerra

20

Auxiliar

0409

Pablo

18

asociado

class ASIGNATURA{
int codigo;
String nombre;
int credito
}

No es Posible
en C++ pero si
en java

class DOCENTE{
int codigo;
String nombre;
int edad;
String categoria
ASIGNATURA curso[] = new ASIGNATURA[5];

USANDO ARCHIVOS DE TEXTO


Podemos abrir un fichero de texto para leer usando la
clase FileReader. Esta clase tiene mtodos que nos
permiten leer caracteres. Sin embargo, suele ser habitual
querer las lneas completas, bien porque nos interesa la
lnea completa, bien para poder analizarla luego y extraer
campos de ella. FileReader no contiene mtodos que
nos permitan leer lneas completas, pero s
BufferedReader. Afortunadamente, podemos construir
un BufferedReader a partir del FileReader.

Para escribir en un archivo de texto lo primero que


tendremos que hacer ser crear un BufferedWriter. Esta
clase nos ayuda a manejar los stream en forma de buffer
con mtodos muy sencillos. Este buffer necesitar saber
cual es el fichero. Esto se lo proporcionamos desde la
clase FileWriter

Usando archivos de texto


import java.io.*;
import java.lang.*;
import java.util.*;
class TEXTO{
PrintStream p=new PrintStream(System.out);
BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
String nombre;
String dato(String mensaje){
System.out.print(mensaje);
try{
nombre=b.readLine( ); }
catch(IOException ioe){ p.println("No se puede leer");
return nombre;
}

Metodo para escribir en un


archivo de texto

public void escritura(String nomb){


String arch = "prueba.dat";
try{
FileWriter fw = new FileWriter ("text.txt",true);
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter salArch = new PrintWriter (bw);
salArch.println(nomb);
salArch.close();
}
catch(java.io.IOException ioex){ }
}

Usando archivos de texto


public void mostrar(){
try {
FileReader fr=new FileReader("text.txt");
BufferedReader entrada=new BufferedReader(fr);
String s;
while((s=entrada.readLine( ) )!=null){ System.out.println("Salida del archivo : "+s);
}
entrada.close();
}
catch(java.io.FileNotFoundException fnfex){
}
catch(java.io.IOException ioex){ }
}

public static void main(String arg[ ]){


TEXTO fun= new TEXTO();
fun.escritura(fun.dato("Ingrese algo al archivo > "));
fun.mostrar();
}
}

Metodo para
visualizar la
informacion de un
archivo de texto

USANDO ARCHIVOS BINARIOS


La clase DataOutputStream, es una extensin de la
clase OutputStream, y aade a sta ltima la
posibilidad de escribir tipos de datos primitivos, pero
no restringidos nicamente a bytes y a matrices de
bytes, como en el caso de OutputStream.

Mediante la clase DataOutputStream


podemos escribir datos de tipo int, float,
double, char, etc.

La clase DataInputStream est diseada para leer


datos
generados
por
un
objeto
DataOutputStream. La especificacin de esta clase
garantiza que cualquier archivo escrito por un
DataOutputStream, sobre cualquier plataforma y
sistema operativo, ser legible correctamente por un
DataInputStream.

Usando archivos binarios


import java.io.*;
import java.lang.*;
import java.util.*;
class BINARIO{
PrintStream p=new PrintStream(System.out);
BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
String nombre;
public String dato(String mensaje){
System.out.print(mensaje);
try{
nombre=b.readLine( ); }
catch(IOException ioe){
p.println("No se puede leer");
}
return nombre;
}

Metodo para escribir en un


archivo de binario

public void escritura(double d1){


try{
DataOutputStream dos= new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("prueba.dat",true)));
dos.writeDouble(d1);
dos.close();
}
catch(java.io.IOException ioex){ }
}

Usando archivos binarios


public void mostrar(){ // PERMITE MOSTRAR EL VALOR REAL EN EL ARCHIVO
String s;
try {
DataInputStream disco=
new DataInputStream(new BufferedInputStream(new FileInputStream("prueba.dat")));
File f= new File("prueba.dat");
double d2;
while(f.exists( ) ){
d2=disco.readDouble( );
System.out.println(d2);
}
disco.close( );
}
catch(java.io.FileNotFoundException fnfex){ }
catch(java.io.IOException ioex){ }
}

public static void main(String arg[ ]){


BINARIO fun= new BINARIO( );
fun.escritura(Float.parseFloat(fun.dato("Ingrese un real > ")));
fun.escritura(Float.parseFloat(fun.dato("Ingrese un real > ")));
fun.mostrar();
}
}

Metodo para
visualizar la
informacion de un
archivo de binario

RANDOMACCESSFILE
RandomAccessFile se usa para los archivos que
contengan registros de tamao conocido, de forma
que se puede mover de un registro a otro utilizando
seek(), para despues leer o modificar los registros.
RandomAccessFile tiene un comportamiento
esencialmente distinto al de otros tipos de E/S,
puesto que se puede avanzar y retroceder dentro de
un archivo.
Fundamentalmente un RandomAccessFile funciona
igual que un DataInputStream unido a un
DataOutputStream junto con los metodos
getFilePointer para averiguar la posicin actual en
el archivo, seek() para moverse a un nuevo punto
del archivo, y length() para determinar el tamao
mximo del mismo.

RANDOMACCESSFILE
import java.lang.*;
import java.io.*;
class ARCH {
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
String n;
int clave=0;
int edad=0;
long tregistro=58;
long cregistros=0;
public String leer(String m){
System.out.print(m+" : ");
try{ n=teclado.readLine( );
catch(Exception e){
return n;
}

}
}

Mtodo para lectura


de datos

Continua la clase ARCH

RANDOMACCESSFILE
void INGRESAR( ){
String nombre="";
try {
File arch=new File("archivo1.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
clave = Integer.parseInt(leer("dame clave"));
nombre=leer("dame nombre");
if (nombre.length( ) < 25){
for(int i=nombre.length( ); i <25; i++)
nombre=nombre+" ";
}
Se registran
else{ nombre=nombre.substring(0,25); };
edad = Integer.parseInt(leer("dame edad"));
con a
lo
if (archivo.length( )!= 0){
caracters
archivo.seek( archivo.length( ) );
};
archivo.writeInt(clave);
archivo.writeChars(nombre);
archivo.writeInt(edad);
archivo.close( );
}
catch(FileNotFoundException f) { System.out.println("Arch. No existe"); }
catch (IOException e) { System.out.println("Error al escribir"); }
}

nombres
mas 25

Continua la clase ARCH

RANDOMACCESSFILE
void ELIMINAR( ){
El mtodo ELIMINAR es muy largo, en
int c1;
esta parte
se busca la clave a
String n1="";
eliminar,cuando se da con ella se
int e1;
captura la posicin en el archivo y
String nombre="";
luego se asigna a k(k = n)
boolean cond=false;
int k;
try{
File arch=new File("archivo1.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
cregistros=archivo.length( ) / tregistro;
int n=0;
int c = Integer.parseInt(leer("dame clave a buscar"));
while(n<cregistros){
archivo.seek(n*58);
clave=archivo.readInt( );
if(clave == c){ cond=true; break;}
n=n+1;
}
k=n;

Continua la clase ARCH

RANDOMACCESSFILE

if(cond){
for(;;){ k++;
if(k< cregistros){
archivo.seek(k*58);
c1=archivo.readInt( );
for(int i = 0; i < 25; ++i){ n1 += archivo.readChar( );};
e1=archivo.readInt( );
archivo.seek(n*58);
archivo.writeInt(c1);
archivo.writeChars(n1);
archivo.writeInt(e1);
n1="";
n++;
}
else { archivo.close( );
File arch2=new File("archivo1.dat");
RandomAccessFile archivo2=new RandomAccessFile(arch,"rw");
archivo2.setLength(n*58);
archivo2.close();
break;
}
Se
comprime el
}
archivo
}
else archivo.close( );
}
catch(FileNotFoundException f) { System.out.println("Arch. no existe"); }
catch (IOException e) { System.out.println("Error al escribir"); }
}
Continua la clase ARCH

RANDOMACCESSFILE
void MOSTRAR( ){
int clave=0;
String nombre="";
int edad=0;
try {
File arch=new File("archivo1.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
cregistros=archivo.length( ) / tregistro;
for (int r=0; r < cregistros; r++){
clave=archivo.readInt( );
for(int i = 0; i < 25; ++i){ nombre += archivo.readChar( ); };
edad=archivo.readInt( );
System.out.println(clave+" "+nombre+" "+edad);
nombre="";
};
archivo.close( );
}
catch(FileNotFoundException f) { System.out.println("Arch. no existe"); }
catch (IOException e) { System.out.println("Error al escribir"); }
}

Continua la clase ARCH

RANDOMACCESSFILE
public static void main(String[ ] args) {
ARCH a=new ARCH();
for(;;){
System.out.println("REGISTRAR <1>\n VER <2>\n ELIMINAR <3>\n SALIR <4>");
switch (Integer.parseInt(a.leer("opcion : "))){
case 1:a.INGRESAR( );break;
case 2:a.MOSTRAR( );break;
case 3:a.ELIMINAR( );break;
case 4:System.exit(0);
}
}
REGISTRAR <1>
} // cierra main

VER <2>
ELIMINAR <3>
SALIR <4>

opcin : : 2
345 CARLOS
789 MARIA

45
12

Que es Serializacin?
La serializacin es el proceso de convertir el
estado de un objeto a un formato que se pueda
almacenar o transportar.
Durante este proceso, los campos pblico y
privado del objeto y el nombre de la clase,
incluido el ensamblado que contiene la clase, se
convierten en una secuencia de bytes que, a
continuacin, se escribe en una secuencia de
datos.
Cuando, despus, el objeto se deserializa, se
crea una copia exacta del objeto original.

Serializacin para
crear un objeto
La serie de bytes o el formato pueden
ser usados para crear un nuevo objeto
que es idntico en todo al original,
incluido su estado interno (por tanto, el
nuevo objeto es un clon del original).

Serializacin para
transporte de objetos
La serializacin es un mecanismo
ampliamente usado para transportar
objetos a travs de una red, para
hacer persistente un objeto en un
archivo o base de datos, o para
distribuir objetos idnticos a varias
aplicaciones o localizaciones.

Soporte de Lenguajes
Varios lenguajes de programacin
orientados a objeto soportan la
serializacin de forma directa.
Algunos de ellos son:

Objective-C
Java
Delphi
C#
Visual Basic .NET
Perl
Python

USANDO SERIALIZACION
La serializacin en Java est presente desde la
versin 1.1 y est incluida en el paquete java.io.
ste contiene la interfaz Serializable, que ser
implementada por la clase que necesita el uso de
esta caracterstica. As mismo, se aaden dos
mtodos a dicha clase, que son:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;

El primero se encargar de almacenar el estado


del objeto en un flujo de datos y el segundo, como
es de esperar, de recuperarlo.

SERIALIZAR UN OBJETO
Para serializar un objeto:

Crear un objeto OutputStream.


Envolverlo dentro un objeto
ObjectOutputStream.
Llamar al mtodo writeObject().

DESERIALIZAR UN OBJETO
Para deserializar:

Crear un InputStream.
Envolverlo dentro de un ObjectInputStream.
Llamar al mtodo readObject().
Se efecta un upcast a Object, por lo que
hay que realizar un downcasting.

USANDO SERIALIZACION
import java.io.*;
public class serial {
public static void main(String args[ ]) {

serializando

//Serializamos el objeto
try {
MiClase obj1 = new MiClase("String", 15);
System.out.println("Objeto 1: " + obj1);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serial"));
oos.writeObject(obj1);
oos.close( );
} catch (Exception e)
{System.out.println("si"+e.getMessage());System.exit(0);}
//Deserializacin del objeto
try {
MiClase obj2;
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serial"));
obj2 = (MiClase)ois.readObject( );
ois.close();
System.out.println("Objeto 2: " + obj2);
} catch(Exception e) {System.out.println(e.getMessage( ));System.exit(0);}
}
}

deserializando

USANDO SERIALIZACION

class MiClase implements Serializable {


String s;
int i;
public MiClase(String s, int i) {
this.s = s;
this.i = i;
}
public String toString() {
return "s=" + s + "; i=" + i;
}
}

Clase serializable

PROBLEMA EN LA
SERIALIZACION
Un problema en el ObjectOutputStream es que al instanciarlo,
escribe unos bytes de cabecera en el fichero, antes incluso de que
escribamos nada. Como el ObjectInputStream lee correctamente
estos bytes de cabecera, aparentemente no pasa nada y ni
siquiera nos enteramos que existen.
El problema se presenta si escribimos unos datos en el fichero y lo
cerramos. Luego volvemos a abrirlo para aadir datos, creando un
nuevo ObjectOutputStream as
Esto escribe una nueva cabecera justo al final del fichero. Luego
se irn aadiendo los objetos que vayamos escribiendo. El fichero
contendr lo del dibujo, con dos cabeceras.

PRIMERA SESION
cabecera

obj1

obj2

SEGUNDA SESION
obj3

cabecera

obj4

obj5

obj6

obj7

PROBLEMA EN LA
SERIALIZACION
PRIMERA SESION
cabecera

obj1

obj2

SEGUNDA SESION
obj3

cabecera

obj4

Qu pasa cuando leamos el fichero?. Al


crear el ObjectInputStream, este lee la
cabecera del principio y luego se pone a leer
objetos. Cuando llegamos a la segunda
cabecera que se aadi al abrir por segunda
vez el fichero para aadirle datos,
obtendremos
un
error
StreamCorruptedException y no podremos
leer ms objetos.
Una solucin es evidente, no usar ms que
un solo ObjectOuptutStream para escribir
todo el fichero. Sin embargo, esto no es
siempre posible.

obj5

obj6

obj7

PROBLEMA EN LA
SERIALIZACION
Una solucin es hacer nuestro propio
ObjectOutputStream, heredando del original y
redefiniendo el mtodo writeStreamHeader()
como en la figura, vaco, para que no haga
nada.

protected void writeStreamHeader() throws IOException


{
// No hacer nada.
}

PRIMERA SESION
cabecera

obj1

obj2

SEGUNDA SESION
obj3

cabecera

obj4

obj5

obj6

obj7

SERIALIZACION CON UN OBJETO


COMPUESTO
class ASIGNATURA implements Serializable{
private String nomb;
private String cred;
void REG(String n, String c ){ nomb=n; cred= c;}
void VIS(){System.out.println("ASIG: "+nomb+" CRED: "+cred);}
}
class ALUMNO implements Serializable {
private int cod;
private String n;
ASIGNATURA a=new ASIGNATURA();
public ALUMNO(String n, int c) {
String asig="",cre="";
this.cod = c;
this.n = n;
asig=PRINCIPAL.leer("leer asignatura: ");
cre=PRINCIPAL.leer("leer credito: ");
a.REG(asig, cre);
}
void VIS(){
System.out.println("COD: "+cod+" NOMB: "+n);
a.VIS();
}
}

Objetos de ambas
clases se
serializaran

SERIALIZACION CON UN
OBJETO COMPUESTO
class MiObjectOutputStream extends ObjectOutputStream{
/** Constructor que recibe OutputStream */
public MiObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
/** Constructor sin parmetros */
protected MiObjectOutputStream() throws IOException, SecurityException {
super();
}
/** Redefinicin del mtodo de escribir la cabecera para que no haga nada. */
protected void writeStreamHeader() throws IOException {
}
}

Redefinicin de la clase ObjectOutputStream


para que no escriba una cabecera al principio
del Stream

SERIALIZACION CON UN
OBJETO COMPUESTO
class PRINCIPAL{
public void escribeFichero(String fichero, String x,int y){
try {
ALUMNO obj1 = new ALUMNO(x,y);
obj1.VIS();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fichero));
oos.writeObject(obj1);
oos.close( );
} catch (Exception e){
{System.out.println(e.getMessage());}
}
}
public void anhadeFichero (String fichero,String x,int y){
try{
ALUMNO obj1 = new ALUMNO(x,y);
obj1.VIS();
MiObjectOutputStream oos = new MiObjectOutputStream(new FileOutputStream(fichero,true));
oos.writeObject(obj1);
oos.close( );
} catch (Exception e){
{System.out.println(e.getMessage());}
Continua la clase
}
PRINCIPAL
}

SERIALIZACION CON UN OBJETO


COMPUESTO
..Continua de la clase PRINCIPAL
public void leeFichero(String fichero){
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fichero));
ALUMNO aux = (ALUMNO)ois.readObject( );
while (aux!=null) {
aux.VIS();
aux = (ALUMNO)ois.readObject();
}
ois.close();
}
catch (EOFException e1) {
System.out.println ("Fin de fichero");
}
catch (Exception e2) {
e2.printStackTrace();
}
}
static String leer(String m){
BufferedReader b= new BufferedReader(new InputStreamReader(System.in));
String c="";
System.out.println(m);
try{ c=b.readLine();}
catch(Exception e){ }
return c;
Continua la clase PRINCIPAL
}

CON UN OBJETO COMPUESTO


void Menu(){
int op=0,cod;
String nom="";
Scanner s=new Scanner(System.in);
for(;;){
System.out.println("\n Registrar <1>\n Aadir <2>\n Visualizar <3>\n Salir
op=s.nextInt();
switch(op){
case 1: nom=leer("leer nombre: ");
cod= Integer.parseInt(leer("leer codigo: "));
escribeFichero("academico",nom, cod);
break;
case 2: nom=leer("leer nombre: ");
cod= Integer.parseInt(leer("leer codigo: "));
anhadeFichero("academico",nom, cod);
break;
case 3: leeFichero("academico");
break;
case 4: System.exit(0);
}//fin del switch
}// fin del for
}
static public void main(String arg[]){
PRINCIPAL p=new PRINCIPAL();
p.Menu();
}
} // FIN DE LA CLASE PRINCIPAL

<4>");

PERSISTENCIA HOY
Salvar los objetos depende del lenguaje en el que se est
trabajando:

JAVA: posee un sistema de serializacin de objetos a


disco, ms o menos automtico.
C++: no posee ningn sistema de serializacin,
utilizndose mecanismos que tienen como base la
grabacin directa de objetos a disco:
fwrite(&objeto, sizeof(objeto), 1,Fichero)

PERSISTENCIA HOY
En los lenguajes como C++, slo puede
recuperarse el estado de un objeto guardado
previamente; sin embargo no puede saberse a
qu clase pertenece el objeto, y ni siquiera si
es un objeto.
En lenguajes como Java, la recuperacin es
un poco mejor, puesto que podemos obtener
el archivo .class y el de datos; sin embargo, la
recuperacin y el tratamiento de estos
archivos slo es realmente sencillo si es la
misma aplicacin que los grab la que los va a
utilizar.

ESENCIA DE LA PERSISTENCIA
La investigacin en persistencia trata de ir un paso
ms all que la idea inicial de guardar objetos en
archivos de la misma forma que es posible guardar
todo tipo de datos en ellos.
Se trata de proporcionar un mecanismo tan
automtico como sea posible para la recuperacin
y salvaguarda de objetos, resultando por tanto
obsoletos los conceptos de:
Archivo: ya no es necesario.
Distincin entre memoria primaria y
secundaria: ya no es necesaria.