Temas:
Sin embargo, existen problemas en donde el volumen de datos es tan grande que es imposible mantenerlos en memoria. Entonces, los datos se almacenan en un conjunto de archivos, los que forman una base de datos. Una base de datos es por lo tanto un conjunto de archivos que almacenan, por ejemplo, datos con respecto al negocio de una empresa.
Cada archivo se forma en base a un conjunto de líneas y cada línea esta formada por campos de información. Todas las líneas de un mismo archivo tienen la misma estructura, es decir los mismos campos de información. Diferentes archivos poseen estructuras distintas, i.e. campos de información.
Por ejemplo, el archivo de postulantes post.dat, visto en capítulos anteriores, tiene la siguiente información:
Por ello es conveniente definir para cada archivo una y sólo una clase que representa la información contenida en una línea del archivo. Para cada uno de los campos del archivo, la clase tiene una variable de instancia con su contenido. Los objetos se construyen a partir de un archivo o a partir de los valores de los campos. La clase suministra un método escribir para colocar el contenido del objeto en un archivo.
Por ejemplo, la clase Post permite representar el contenido de una línea del archivo post.dat:
Todos los programas que usen archivos con estos mismos campos usarán
esta clase. Si se agregan o quitan campos a estos archivos, basta
cambiar la definición de la clase para que la mayoría de los programas
que usan esta estructura de archivos ya puedan usar el nuevo formato.
Solo será necesario cambiar los programas que usan los campos que fueron
suprimidos o que requieren utilizar los que se hayan agregado.
class Post {
String ci= ""; // Los campos de una línea
String nombre= "";
Post(String ci, String nombre) {
this.ci= ci;
this.nombre= nombre;
}
// Lee del archivo los campos en el formato
// ci:nombre
Post(TextReader lect) {
if (lect.eofReached())
this.ci= null;
else {
this.ci= lect.readString();
this.nombre= lect.readString();
lect.skip();
}
}
// Escribe los campos en el formato ci:nombre:cuenta
void escribir(TextWriter escr) {
escr.print(ci);
escr.println(nombre);
}
}
Ejercicio:
Escriba una clase similar para el archivo mat.dat. La clase se debe llamar Mat.
Se elige esta organización porque todo problema de representación de información se puede llevar a una base de datos. Además cualquier problema de manipulación de la información se puede reducir a una combinación de los siguientes patrones:
Ejemplo de selección:
Se necesita un archivo mat450.dat con el carnet de identidad y puntaje de las personas que obtuvieron más de 450 puntos en la prueba de matemáticas:
Ejemplo de Proyección:
TextReader lect= new TextReader("mat.dat", ":");
TextWriter escr= new TextWriter("mat450.dat", ":");
while (!lect.eofReached()) {
Mat mat= new Mat(lect);
if (mat.ptje>=450)
mat.escribir(escr);
}
lect.close();
escr.close();
Los carnet de identidad y nombre de los alumnos que aparecen en post-mat.dat:
TextReader lect= new TextReader("post-mat.dat", ":");
TextWriter escr= new TextWriter("post-mat-proy.dat", ":");
while (!lect.eofReached()) {
PostMat postMat= new PostMat(lect);
Post post= new Post(postMat.ci, postMat.nombre);
post.escribir(escr);
}
lect.close();
escr.close();
Archivo | Campos | Clase |
---|---|---|
post.dat | ci, nombre | Post |
mat.dat | ci, ptje | Mat |
post-mat.dat | ci, nombre, ptje | PostMat |
El programa que realiza el pareo es:
(El programa completo se encuentra en Pareo.java.
Los archivos de prueba son post.dat
y mat.dat.)
TextReader postLect= new TextReader("post.dat", ":");
TextReader matLect= new TextReader("mat.dat", ":");
TextWriter escr= new TextWriter("post-mat.dat", ":");
Post post= new Post(postLect);
Mat mat= new Mat(matLect);
while (post.ci!=null && mat.ci!=null) {
int cmp= compare(post.ci, mat.ci);
if (cmp<0)
post= new Post(postLect);
else if (cmp>0)
mat= new Mat(postMat);
else {
PostMat postMat=
new PostMat(post.ci, post.nombre, mat.ptje);
postMat.escribir(escr);
post= new Post(postLect);
mat= new Mat(matLect);
}
}
escr.close();
postLect.close();
postLect.close();
Este programa lee una y solo una vez cada línea de los archivos de entrada y por lo tanto toma tiempo proporcional a la suma de las líneas en ambos archivos.
El problema que dejaremos pendiente es cómo ordenar este tipo de archivos. Todos los algoritmos de ordenamiento que hemos visto hasta el momento trabajan con arreglos. Luego veremos un algoritmo que permite ordenar archivos sin tener que leer todo su contenido en la memoria del computador.
Desde luego, en muchas ocasiones se pueden combinar los patrones sin tener que pasar por archivos intermedios. Por ejemplo se puede hacer un pareo que incorpore una selección y una proyección en una sola lectura de los archivos. Sin embargo, el acumular demasiados patrones puede hacer un programa completamente ilegible. ¡Nunca intente ahorrar líneas de programa combinando dos pareos en un sólo ciclo!
El siguiente programa lee el archivo post.dat y produce 2 archivos: uno contiene las personas que aparecen una sola vez (unicos.dat) y el otro almacena las que aparecen 2 o más veces (dups.dat). Por ejemplo si el archivo fuese:
Los archivos producidos serán:
post.dat
------------
10000:Pedro
20000:Diego
20000:Diego
30000:Juan
60000:Sutano
80000:Megano
80000:Megano
El programa supone que el archivo está ordenado por carnet de identidad.
unicos.dat dups.dat
---------- --------
10000:Pedro 20000:Diego
30000:Juan 20000:Diego
60000:Sutano 80000:Megano
80000:Megano
TextReader lect= new TextReader("post.dat");
TextWriter escr= new TextWriter("unicos.dat");
TextWriter escrDup= new TextWriter("dups.dat");
Post post= new Post(lect);
while (post.ci!=null) {
Post sgte= new Post(lect);
if (sgte.ci==null || compare(post.ci, sgte.ci)!=0)
post.escribir(escr);
else {
post.escribir(escrDup);
while(sgte.ci!=null && compare(post.ci, sgte.ci)==0) {
sgte.escribir(escrDup);
sgte= new Post(lect);
}
}
post= sgte;
}
lect.close();
escr.close();
escrDup.close();
Ejercicio propuesto:
Escriba completamente uno o más programas que entreguen los nombres de los 20000 mejores puntajes en la prueba de matemáticas. Su programa debe ser eficiente en tiempo de ejecución.
Indicación: