Estructura de Datos Filas
-
Upload
martin-guevara -
Category
Documents
-
view
66 -
download
1
description
Transcript of Estructura de Datos Filas
Estructura De Datos
Docente: Carlos A. Ruiz De La Cruz Melo
Correo: [email protected]
ALGORITMICA III
PERSISTENCIA
Capacidad para conseguir que losdatos sobrevivan a la ejecución delproceso que los creo, de forma quepuedan ser reutilizados en otroproceso.
Se entiende por persistencia en laprogramación orientada a objetoscomo la capacidad que tienen losobjetos de conservar su estado eidentidad entre distintas ejecucionesdel programa que los creó o de otrosprogramas que accedan a ellos.
La persistencia no es ni unacapacidad ni una propiedad de laPOO, no tiene nada que ver con elparadigma en sí, solo es elmecanismo que se usa para persistirinformación de un determinado tipo(como puede ser serializar, guardar losdatos en una tabla, en un archivoplano, etc).
Persistencia como mecanismo
Los objetos para lapersistencia
Una instancia persistente esaquella cuyos datos perduran ala ejecución del proceso quematerializo la instancia.
Una instancia transitoria estoda instancia cuyos datosdesaparecen cuando finalizanlos procesos que la manipulan
Objetivos de lapersistencia
La persistencia permite alprogramador almacenar, transferir yrecuperar el estado de los objetos.Para esto existen varias técnicas:
SerializacionMotores de persistenciaBases de datos orientadas a objetos
Un archivo o fichero de datos es unacolección de registros relacionadosentre si con aspectos en común yorganizados para un propósitoespecifico.
Un archivo en una computadora esuna estructura diseñada paracontener datos, estos estánorganizados de tal modo que puedanser recuperados fácilmente,actualizados o borrados yalmacenados de nuevo en el archivocon todos los cambios realizados
ARCHIVOS/FILAS
Este tema se centra en el uso de los archivoscomo flujos de datos de un programa, tanto deentrada, para proporcionar los datos necesariospara realizar la tarea que ejecuta el programa,como de salida, para almacenar los datosobtenidos por el programa.
Se puede considerar un flujo como una secuenciade caracteres.
ARCHIVOS/FILAS
Todos los datos fluyen a través del ordenador desde una entrada haciauna salida.
Este flujo de datos se denomina también stream.
Hay un flujo de entrada (input stream) que manda los datos desde elexterior (normalmente el teclado) del ordenador, y un flujo de salida(output stream) que dirige los datos hacia los dispositivos de salida (lapantalla o un archivo).
FLUJOS
El proceso para leer o escribir datos consta de tres pasos
Abrir el flujo de datos
Mientras exista más información (leer o escribir ) los datos
Cerrar el flujo de datos
ORGANIZACION
Organización secuencial Organización directa Organización indexada
La organización de un archivo define la formaen la que los registros se disponen sobre elsoporte de almacenamiento, o también sedefine la organización como la forma en quese estructuran los datos en un archivo. Engeneral, se consideran tres organizacionesfundamentales:
MEMORIA PRIMARIA
MEMORIA SECUNDARIA
APLICACIÓN
Archivos DISCO
0 1 2 3
Listas
Arreglos
ARCHIVO EN C++ O EN JAVA
Para C++ es un dispositivo
externo hacia/desde el cual
puede fluir información.
micrófono
Cinta magnética
impresora
Disco duro
Archivos binarios /
texto
Tipo de archivo que
se usara para filas
secuenciales
ARCHIVO BINARIO/TEXTO
Almacenamiento
en archivo
texto
Binario
Almacena caracteres ASCII
Visible por un editor
Almacena en hexadecimal
No visible por cualquier
editor
Dividido en segmentos
ARCHIVO BINARIO
REGISTRO 1
REGISTRO 2
REGISTRO N-1
REGISTRO N
:
EOF
Dividido en segmentos
de igual tamaño
Marca de fin de archivo
(End of File)
Estructura de un
archivo binario
UBICACIÓN LÓGICA Y FÍSICA
CODIGO NOMBRE NOTA
90021 Carlos Rojas Sánchez 10
89765 Manuel Ventura Díaz 11
78560 Ana Alvarado Gálvez 15
lógica física
0 0
1 56
2 112
Especificación ALUMNO
variables
entero : código
cadena: nombre
real : nota
operaciones
significado
Fin_ALUMNO
En C++Suponemos que
código, nombre y
nota suma en total
56 bytes
ACCESO AL DISCO
Para empezar, los discos distribuyen los datos endos o tres dimensiones. Las cabezas delectura/escritura se mueven a lo largo del radiodel disco, a distancias preestablecidas. Cada unade esas distancias define una pista
A su vez, cada pista está dividida en partes máspequeñas, llamadas sectores.
cada disco está compuesto en realidad por variosdiscos llamados platos, cada plato tiene doscaras, y en cada cara se coloca una cabeza delectura/escritura.
De modo que para acceder a un dato seránecesario calcular en qué plato, pista y sectorestá almacenado, mover la cabeza a la pistaadecuada y esperar a que el sector pase pordebajo de la cabeza correspondiente al platoindicado
La unidad mínima que se puede leer oescribir en un disco es un sector. El tamañodel sector es variable, generalmente son de512 bytes, pero pueden ser diferentes.
El sistema operativo no trabaja directamentecon sectores, sino con clusters. Cadacluster tiene un número entero de sectores.
Una velocidad de 5400RPM permitirá unatransferencia entre 10MB y 16MB porsegundo con los datos que están en laparte exterior del cilindro o plato, algomenos en el interior.
Aún cuando los microprocesadoresutilizados en los discos duros sonrelativamente poderosos, las tareasasignadas a ellos toman tiempo en llevarsea cabo. En promedio, este tiempo está en elrango de los .003 milisegundos.
ACCESO AL DISCO
ORGANIZACIÓN SECUENCIAL
La Fila secuencial es una estructurade datos lineal en la cual loselementos están dispuestos uno trasde otro, de tal modo que en lasoperaciones para manipular loselementos se respeta la secuenciade los mismos en la estructura.
Registro 1
Registro 1
:
Registro 1
:
Registro N-1
Registro N
Inicio de
archivo
fin de
archivo
ORGANIZACIÓN SECUENCIAL Accesar el próximo registro es trivial.
Para agregar registros a un archivosecuencial hay dos opciones: Crear un nuevo archivo. Agregar al final del archivo.
Para eliminar los registros estos sepueden marcar (necesidad de uncampo extra) o se debe crear unnuevo archivo.
Los archivos secuenciales ocupan untamaño mínimo, o sea, sólo el espaciorequerido para el almacenamiento delos registros.
ORGANIZACIÓN DIRECTA
Los datos se colocan y seacceden aleatoriamentemediante su posición, esdecir, indicando el lugarrelativo que ocupandentro del conjunto deposiciones posibles.
En esta organización sepueden leer y escribirregistros, en cualquierorden y en cualquier lugar.
Ventaja
Rapidez de acceso a unregistro cualquiera
Desventajas
Establecer la relación entrela posición que ocupa unregistro y su contenido;
Puede desaprovecharseparte del espacio destinadoal archivo
ORGANIZACIÓN DIRECTA
ORGANIZACIÓN INDEXADA
Un archivo con esta organizaciónconsta de dos áreas:
Archivo de índices Archivo de datos
CLAVE DIRECCION
234 010
345 020
422 030
467 040
: :
678 090
CLAVE DATOS
010 234
011 234
:
019 234
020 345
021 345
:
029 345
030 422
:
039 422
AREA DE INDICES
AREA DE DATOS
ORGANIZACIÓN INDEXADA
# Razón fecha Dir.
01 A 01/01/11 0
02 B 02/05/12 342
08 C 14/07/12 570
010 D 20/09/12 684
# Cod. Descrip. Pu cant
01 11 P 2 10
01 18 Q 1 20
01 01 M 3 5
02 09 Y 4.5 3
02 11 P 2 15
08 01 M 3 4
010 03 W 0.5 30
01- Razon: A
Fecha: 01/01/11
cod Descrip PU CANT
11 P 2 10
18 Q 1 20
01 M 3 5
Fila de INDICE
Fila de DATO
0
342
570
684
Dirección física
Cada objeto defila DATOStiene 114 bytes
ORGANIZACIÓN INDEXADA
Ventaja Rápido acceso, y, además, el sistema se
encarga de relacionar la posición de cadaregistro con su contenido por medio delárea de índices.
Gestiona las áreas de índices yexcedentes.
Desventajas Necesidad de espacio adicional para el
área de índices. El desaprovechamiento de espacio que
resulta al quedar huecos intermedios libresdespués de sucesivas actualizaciones.
Se pueden considerar tres criterios básicos:
Rápido Acceso Economía de
Almacenamiento Facilidad de Uso
CRITERIOS PARA ELEGIR UN TIPO DE ORGANIZACIÓN
La elección de la organizacióndetermina el rendimiento relativo delsistema para cada una de las trescaracterísticas enunciadas:
ALGUNAS MEDIDAS DE RENDIMIENTO
Almacenamiento requerido por unregistro.
Tiempo de búsqueda de un registro. Tiempo requerido para leer todo el
archivo. Tiempo requerido para insertar un
registro. Tiempo para modificar un registro.
Rápido Acceso
Economía de
Almacenamiento
Facilidad de Uso
PRIMITIVAS
inicio( F )
Para F : identificador de fila/archivo/fichero
v : variable del mismo tipo de dato que almacena la fila
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 posición p de la fila F
comprimir( F, p ) Escribe una cantidad de objetos P en la fila F
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(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
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0344 Juan
0944 Ana
0723 Jorge
Encontrar primero código
0344
k = i
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0344 Juan
0944 Ana
0723 Jorge
k
i
Se elimino el código
0344
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0944 Ana
0944 Ana
0723 Jorge
k
i
Se elimino el código
0344
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0944 Ana
0944 Ana
0723 Jorgek
i
Se elimino el código
0344
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0944 Ana
0723 Jorge
0723 Jorgek
i
Se elimino el código
0344
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0944 Ana
0723 Jorge
0723 Jorgek
i
Se elimino el código
0344
function eliminar(): enteroALUMNO: a,pentero: i, i0condfalsosalirverdaderoinicio(base)leer( cod)leer(base, a)mientras no ultimo(base) y salir hacer
si (a.codigo=cod) entoncescondverdaderosalirfalso
sinoii+1
finsileer(base, a)
finmientraskisalirverdaderosi(cond = verdadero) entonces
mientras(salir=verdadero) hacer kk+1ubicar(base,k)leer(base,p)si (no ultimo(base)) entonces
ubicar(base, i)escribir(base, p)ii+1
sinocerrar(base)inicio(base) comprimir(base, i)cerrar(base)
salirfalsofinsi
finmientrassino
cerrar(base)finsi
fineliminar
ORGANIZACIÓN DIRECTA
código nombre
0123 Carlos
0856 María
0944 Ana
0723 Jorge
Se elimino el código
0344
i
PERSISTENCIA EN C++
ARCHIVOSPosible en C++ código nombre edad
01 Juan 20
04 María 18
class PERSONA{int codigo;String nombre;int edad
}
código nombre credito
01112 Estadística 4
04023 Matemática I 4
08999 Algoritmica 3
código nombre edad categoria
0177 Guerra 20 Auxiliar
0409 Pablo 18 asociado
class ASIGNATURA{int codigo;String nombre;int credito
}
class DOCENTE{int codigo;String nombre;int edad;String categoriaASIGNATURA curso[] = new ASIGNATURA[5];
}
AS
IGN
AT
UR
AD
OC
EN
TE
No es Posible
en C++
MANEJO DE FILAS EN CActualmente existen tres formas para manejar los archivosen lenguaje C, entre los dos primeros, uno llamado deprimer nivel (también llamado secuencial) y otro llamado desegundo nivel (también llamado tipo registro o de alto nivel).
1. En el nivel más bajo se considera el archivo como unconjunto de bytes continuos, esto sin tener en cuentacomo se han grabado, un usuario puede leer lacantidad de bytes que desee no importando laposición en la cual se encuentren éstos.
2. En el modo de más alto nivel se puede acceder a unoo varios registros, es decir, lo que se lee cada vez esuna agrupación lógica. Las operaciones de primernivel, como se las llama a las de nivel más bajo, sonlas más potentes. Se dice que estas operaciones sonlas primitivas del sistema: son las operacionesbásicas. Las de segundo nivel se construyen a partirde éstas.
La siguiente tabla muestra las instrucciones de primer nivelpara manejo de archivos. Todas estas funciones seencuentran definidas en el archivo io.h.
INSTRUCCIONES A BAJO NIVEL
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
0x01 Sólo Lectura O_RDONLY 0x02 Sólo Escritura O_WRONLY 0x04 Lectura/Escritura O_RDWR
Modos de acceso al archivo:
#include <stdio.h>#include <io.h>void main() {
int f, modo=0x01;if( (f= open("Nombre1", modo))==-1){
printf("NO se puede abrir ! ");}
}
INSTRUCCIONES A BAJO NIVEL
Para este ejemplo el archivoNOMBRE1 debe existir. Si NOexiste la función open devuelve -1
#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 !");
}
Si el archivo NO existe locrea. El acceso será delectura-escritura. Todo loque escriba en el archivoborrará la informaciónexistente. Si el modo esO_RDONLY, sólo se podráleer
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 Descripción
0 Principio del archivo
1 Posición actual en el archivo
2 Al final del archivo
INSTRUCCIONES DE SEGUNDO NIVELEn las instrucciones de segundo nivel los archivosya no se designan por un número, sino, por unpuntero a una estructura compleja llamada FILEcuya descripción se haya en el archivo stdio.h.
Apertura de archivo
FILE *fopen(char *nombrefich, char *modo);
Modo Descripción
"r" Para lectura solamente
"w" Para escritura solamente (si el archivo ya existiera lo
borra)
"a" Añadir al final de un archivo que ya existe.
"r+" Actualizar uno que ya existe
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); /* Análoga a lseek */
Condición de fin de archivo
int feof(FILE *fp);
Posicionamiento al comienzo de un archivo
rewind(FILE *fp);
INSTRUCCIONES DE SEGUNDO NIVEL
MANEJO DE FILAS EN C++
En C++, se utilizan streams (flujos)para gestionar la lectura y escritura dedatos. Ya conocemos dos flujosestándar: cin y cout.
En definitiva, abrir un fichero significadefinir un stream. Dicho stream permitela transferencia de datos entre elprograma y el fichero en disco
El buffer es un área de memoriasituada en la RAM asignada alprograma que abre el archivo
MANEJO DE FILAS EN C++ Toda transferencia de datos entre el programa y
el fichero en disco se realiza a través del buffer. El buffer está para dar eficiencia.
Las operaciones de E/S son más eficientes:
El acceso a la memoria RAM consumemenos tiempo que el acceso a undispositivo físico.
El buffer hace que el número de accesos alfichero físico sea menor.
El uso del buffer permite realizar operaciones de
entrada salida de forma más eficiente.
Para poder manipular archivos, C++ dispone de labiblioteca estandar fstream (file stream) donde seencuentran todas las funciones necesarias para abrir ycerrar archivos, así como para realizar las operacionesde lectura y escritura de datos en archivos.
MANEJO DE FILAS EN C++
C++ provee las siguientes clases para realizaroperaciones de entrada y salida de carácteres hacia odesde archivos:
ofstream: El flujo para escribir archivos. ifstream: El flujo para leer archivos. fstream: Flujo de lectura/escritura sobre archivos
#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;}
}}
PROGRAMA DE FILAS EN C++
PERSISTENCIA EN JAVA
Si bien pudieran encontrarse otrosmecanismos alternativos, es posible queresultaran problemáticos y dieran lugar aerrores, e incluso podrían llegar acomplicarse si se necesitara realizar unseguimiento de la jerarquía de los objetos.
En el caso en el que se debiera escribiruna aplicación para una gran empresa quecontenga varios miles de objetos y setuviera que escribir código para guardar enun disco y recuperar desde éste loscampos y propiedades para cada objeto, laserialización proporcionaría el mecanismoadecuado para conseguir este objetivo conel mínimo esfuerzo.
PERSISTENCIA EN JAVAARCHIVOS
código nombre edad
01 Juan 20
04 María 18
class PERSONA{int codigo;String nombre;int edad
}
SERIALIZACION
código nombre credito
01112 Estadística 4
04023 Matemática I 4
08999 Algoritmica 3
código nombre edad categoria
0177 Guerra 20 Auxiliar
0409 Pablo 18 asociado
class ASIGNATURA{int codigo;String nombre;int credito
}
class DOCENTE{int codigo;String nombre;int edad;String categoriaASIGNATURA curso[] = new ASIGNATURA[5];
}
AS
IGN
AT
UR
AD
OC
EN
TE
No es Posible
en C++ pero si
en java
Podemos abrir un fichero de texto para leer usando laclase FileReader. Esta clase tiene métodos que nospermiten leer caracteres. Sin embargo, suele ser habitualquerer las líneas completas, bien porque nos interesa lalínea completa, bien para poder analizarla luego y extraercampos de ella. FileReader no contiene métodos quenos permitan leer líneas completas, pero síBufferedReader. Afortunadamente, podemos construirun BufferedReader a partir del FileReader.
Para escribir en un archivo de texto lo primero quetendremos que hacer será crear un BufferedWriter. Estaclase nos ayuda a manejar los stream en forma de buffercon métodos muy sencillos. Este buffer necesitará sabercual es el fichero. Esto se lo proporcionamos desde laclase FileWriter
USANDO ARCHIVOS DE TEXTO
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;
}
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){ }
}
Metodo para escribir en un
archivo 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();
}
}
Usando archivos de texto
Metodo para
visualizar la
informacion de un
archivo de texto
La clase DataOutputStream, es una extensión de laclase OutputStream, y añade a ésta última laposibilidad de escribir tipos de datos primitivos, perono restringidos únicamente a bytes y a matrices debytes, como en el caso de OutputStream.
Mediante la clase DataOutputStream
podemos escribir datos de tipo int, float,double, char, etc.
La clase DataInputStream está diseñada para leerdatos generados por un objetoDataOutputStream. La especificación de esta clasegarantiza que cualquier archivo escrito por unDataOutputStream, sobre cualquier plataforma ysistema operativo, será legible correctamente por unDataInputStream.
USANDO ARCHIVOS BINARIOS
Usando archivos binariosimport 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;
}
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){ }
}
Metodo para escribir en un
archivo de binario
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();
}
}
Usando archivos binarios
Metodo para
visualizar la
informacion de un
archivo de binario
RANDOMACCESSFILE
RandomAccessFile se usa para los archivos quecontengan registros de tamaño conocido, de formaque se puede mover de un registro a otro utilizandoseek(), para despues leer o modificar los registros.
RandomAccessFile tiene un comportamientoesencialmente distinto al de otros tipos de E/S,puesto que se puede avanzar y retroceder dentro deun archivo.
Fundamentalmente un RandomAccessFile funcionaigual que un DataInputStream unido a unDataOutputStream junto con los metodosgetFilePointer para averiguar la posición actual enel archivo, seek() para moverse a un nuevo puntodel archivo, y length() para determinar el tamañomáximo del mismo.
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;
}
RANDOMACCESSFILE
Método para lectura
de datos
Continua la clase ARCH…
RANDOMACCESSFILEvoid 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+" ";
}else{ nombre=nombre.substring(0,25); };edad = Integer.parseInt(leer("dame edad"));if (archivo.length( )!= 0){
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"); }
}
Se registran nombres
con a lo mas 25
caracters
…Continua la clase ARCH…
void ELIMINAR( ){int c1;String n1="";int e1;String nombre="";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;
RANDOMACCESSFILE
…Continua la clase ARCH…
El método ELIMINAR es muy largo, en
esta parte se busca la clave a
eliminar,…cuando se da con ella se
captura la posición en el archivo y
luego se asigna a k(k = n)
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;
}}
}else archivo.close( );
}catch(FileNotFoundException f) { System.out.println("Arch. no existe"); }catch (IOException e) { System.out.println("Error al escribir"); } }
Se comprime el
archivo
RANDOMACCESSFILE
…Continua la clase ARCH…
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"); }
}
RANDOMACCESSFILE
…Continua la clase ARCH…
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); }
}} // cierra main
RANDOMACCESSFILE
REGISTRAR <1>
VER <2>
ELIMINAR <3>
SALIR <4>
opción : : 2
345 CARLOS 45
789 MARIA 12
Que es Serialización?
La serialización es el proceso de convertir elestado de un objeto a un formato que se puedaalmacenar o transportar.
Durante este proceso, los campos público yprivado del objeto y el nombre de la clase,incluido el ensamblado que contiene la clase, seconvierten en una secuencia de bytes que, acontinuación, se escribe en una secuencia dedatos.
Cuando, después, el objeto se deserializa, secrea una copia exacta del objeto original.
La serie de bytes o el formato puedenser usados para crear un nuevo objetoque es idéntico en todo al original,incluido su estado interno (por tanto, elnuevo objeto es un clon del original).
Serialización paracrear un objeto
La serialización es un mecanismoampliamente usado para transportarobjetos a través de una red, parahacer persistente un objeto en unarchivo o base de datos, o paradistribuir objetos idénticos a variasaplicaciones o localizaciones.
Serialización paratransporte de objetos
Soporte de Lenguajes
Varios lenguajes de programaciónorientados a objeto soportan laserialización de forma directa.
Algunos de ellos son:
Objective-C Java Delphi C# Visual Basic .NET Perl Python
USANDO SERIALIZACION
La serialización en Java está presente desde laversión 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 deesta característica. Así mismo, se añaden dosmétodos 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 estadodel objeto en un flujo de datos y el segundo, comoes de esperar, de recuperarlo.
Para serializar un objeto:
Crear un objeto OutputStream. Envolverlo dentro un objeto
ObjectOutputStream. Llamar al método writeObject().
SERIALIZAR UN OBJETO
DESERIALIZAR UN OBJETO
Para deserializar:
Crear un InputStream. Envolverlo dentro de un ObjectInputStream. Llamar al método readObject(). Se efectúa un upcast a Object, por lo que
hay que realizar un downcasting.
import java.io.*;
public class serial {
public static void main(String args[ ]) {
//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);}
//Deserialización 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);}
}
}
USANDO SERIALIZACION
serializando
deserializando
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;
}
}
USANDO SERIALIZACION
Clase serializable
Un problema en el ObjectOutputStream es que al instanciarlo,escribe unos bytes de cabecera en el fichero, antes incluso de queescribamos nada. Como el ObjectInputStream lee correctamenteestos bytes de cabecera, aparentemente no pasa nada y nisiquiera nos enteramos que existen.
El problema se presenta si escribimos unos datos en el fichero y locerramos. Luego volvemos a abrirlo para añadir datos, creando unnuevo ObjectOutputStream así
Esto escribe una nueva cabecera justo al final del fichero. Luegose irán añadiendo los objetos que vayamos escribiendo. El ficherocontendrá lo del dibujo, con dos cabeceras.
PROBLEMA EN LA SERIALIZACION
PRIMERA SESION SEGUNDA SESION
cabecera obj1 obj2 obj3 cabecera obj4 obj5 obj6 obj7
PROBLEMA EN LA SERIALIZACION
PRIMERA SESION SEGUNDA SESION
cabecera obj1 obj2 obj3 cabecera obj4 obj5 obj6 obj7
¿Qué pasa cuando leamos el fichero?. Alcrear el ObjectInputStream, este lee lacabecera del principio y luego se pone a leerobjetos. Cuando llegamos a la segundacabecera que se añadió al abrir por segundavez el fichero para añadirle datos,obtendremos un errorStreamCorruptedException y no podremosleer más objetos.
Una solución es evidente, no usar más queun solo ObjectOuptutStream para escribirtodo el fichero. Sin embargo, esto no essiempre posible.
protected void writeStreamHeader() throws IOException
{
// No hacer nada.
}
PROBLEMA EN LA SERIALIZACION
PRIMERA SESION SEGUNDA SESION
cabecera obj1 obj2 obj3 cabecera obj4 obj5 obj6 obj7
Una solución es hacer nuestro propioObjectOutputStream, heredando del original yredefiniendo el método writeStreamHeader()
como en la figura, vacío, para que no haganada.
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
class MiObjectOutputStream extends ObjectOutputStream{/** Constructor que recibe OutputStream */public MiObjectOutputStream(OutputStream out) throws IOException {
super(out);}
/** Constructor sin parámetros */protected MiObjectOutputStream() throws IOException, SecurityException {
super();}
/** Redefinición del método de escribir la cabecera para que no haga nada. */protected void writeStreamHeader() throws IOException {}
}
SERIALIZACION CON UN OBJETO COMPUESTO
Redefinición de la clase ObjectOutputStream
para que no escriba una cabecera al principio
del Stream
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());}
}}
SERIALIZACION CON UN OBJETO COMPUESTO
Continua 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;
}
SERIALIZACION CON UN OBJETO COMPUESTO
…..Continua de la clase PRINCIPAL
Continua la clase PRINCIPAL…
void Menu(){int op=0,cod;String nom=""; Scanner s=new Scanner(System.in);for(;;){System.out.println("\n Registrar <1>\n Añadir <2>\n Visualizar <3>\n Salir <4>");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
CON UN OBJETO COMPUESTO
PERSISTENCIA HOY
JAVA: posee un sistema de serialización de objetos a
disco, más o menos automático.
C++: no posee ningún sistema de serialización,
utilizándose mecanismos que tienen como base la
grabación directa de objetos a disco:
fwrite(&objeto, sizeof(objeto), 1,Fichero)
Salvar los objetos depende del lenguaje en el que se esté
trabajando:
PERSISTENCIA HOY
En los lenguajes como C++, sólo puederecuperarse el estado de un objeto guardadopreviamente; sin embargo no puede saberse aqué clase pertenece el objeto, y ni siquiera sies un objeto.
En lenguajes como Java, la recuperación esun poco mejor, puesto que podemos obtenerel archivo .class y el de datos; sin embargo, larecuperación y el tratamiento de estosarchivos sólo es realmente sencillo si es lamisma aplicación que los grabó la que los va autilizar.
ESENCIA DE LA PERSISTENCIA
La investigación en persistencia trata de ir un paso
más 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
automático como sea posible para la recuperación
y salvaguarda de objetos, resultando por tanto
obsoletos los conceptos de:
Archivo: ya no es necesario.
Distinción entre memoria primaria y
secundaria: ya no es necesaria.