Temas:
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 Cuenta permite representar el contenido de una línea del archivo cuentas.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 Cuenta {
String ci= ""; // Los campos de una línea
String nombre= "";
String cuenta= "";
Cuenta(String ci, String nombre, String cuenta) {
this.ci= ci;
this.nombre= nombre;
this.cuenta= cuenta;
}
// Lee del archivo los campos en el formato
// ci:nombre:cuenta
Cuenta(TextReader lect) {
String lin= lect.readLine();
if (!lect.eofReached()) {
FieldParser decod= new FieldParser(lin, ":");
ci= decod.readString();
nombre= decod.readString();
cuenta= decod.readString();
}
}
// Escribe los campos en el formato ci:nombre:cuenta
void escribir(TextWriter escr) {
escr.println(ci+":"+nombre+":"+cuenta);
}
}
Solución para el pareo de archivos
El problema consiste en leer secuencialmente los archivos cuentas.dat y saldos.dat y producir un archivo saldos-cuentas.dat que contenga las cuentas que aparecen en ambos archivos. La siguiente tabla muestra para cada archivo los campos que contiene y la clase que permite manipular sus líneas:
| Archivo | Campos | Clase |
|---|---|---|
| cuentas.dat | ci, nombre, cuenta | Cuenta |
| saldos.dat | cuenta, saldo | Saldo |
| cuentas-saldos.dat | ci, nombre, cuenta, saldo | CuentaSaldo |
El programa que realiza el pareo es:
TextReader lect= new TextReader("cuentas.dat");
TextReader saldosLect= new TextReader("saldos.dat");
TextWriter escr= new TextWriter("cuentas-saldos.dat");
Saldo sal= new Saldo(saldosLect);
Cuenta cuen= new Cuenta(lect);
while (!lect.eofReached() && ! saldosLect.eofReached()) {
int cmp= compare(cuen.cuenta, sal.cuenta);
if (cmp<0)
cuen= new Cuenta(lect);
else if (cmp>0)
sal= new Saldo(saldosLect);
else {
CuentaSaldo cuenSal=
new CuentaSaldo(cuen.ci, cuen.nombre,
cuen.cuenta, sal.saldo);
cuen.escribir(escr);
cuen= new Cuenta(lect);
sal= new Saldo(saldosLect);
}
}
escr.close();
lect.close();
saldosLect.close();
El siguiente programa lee el archivo cuentas.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:
cuentas2.dat
------------
10000:Pedro:100
20000:Diego:104
20000:Diego:104
30000:Juan:101
60000:Sutano:107
80000:Megano:109
80000:Megano:110
El programa supone que el archivo está ordenado por carnet de identidad.
Más tarde examinaremos cómo es posible ordenar archivos cuando caben
en memoria.
unicos.dat dups.dat
---------- --------
10000:Pedro:100 20000:Diego:104
30000:Juan:101 20000:Diego:104
60000:Sutano:107 80000:Megano:109
80000:Megano:109
TextReader lect= new TextReader("cuentas2.dat");
TextWriter escr= new TextWriter("unicos.dat");
TextWriter escrDup= new TextWriter("dups.dat");
Cuenta cuen= new Cuenta(lect);
while (!lect.eofReached()) {
Cuenta sgte= new Cuenta(lect);
if (compare(cuen.ci, sgte.ci)!=0)
cuen.escribir(escr);
else {
cuen.escribir(escrDup);
while(compare(cuen.ci, sgte.ci)==0) {
sgte.escribir(escrDup);
sgte= new Cuenta(lect);
}
}
cuen= sgte;
}
lect.close();
escr.close();
escrDup.close();