You are on page 1of 12

UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

Fichadeclasenmero:10
Fecha: Semanadel11/05al15/05de2009
Docente: Ing.ValerioFrittelli

TemaPrincipal: Gestin de Metadatos.

TemasParticulares: Concepto de metadato. Inclusin de metadatos en un archivo de


registros. Operaciones bsicas en el archivo a partir de sus
metadatos. Breve anlisis de formato dbf.

1.) Introduccin.

En muchos casos una aplicacin de gestin debe poder abrir un archivo del cual se sabe
que contiene registros o datos estructurados en alguna forma, pero sin saber cul es la
estructura del registro: ni el programador ni el programa saben cuntos campos hay en cada
registro, cmo se llama cada campo, de qu tipo son, cul es la longitud de cada uno (si se
aplica este concepto), etc.

Es claro que los datos que constituyen la estructura del registro son datos acerca de los
datos reales que contiene el archivo, y se designa con el nombre de metadatos a esos datos
acerca de los datos.

Un archivo...

legajo 20 12 34 23
nombre Juan Ana Pedro Luis
sueldo 734.45 994.25 831.50 824.23

Datos

Metadatos

Tambin es claro que si una aplicacin debe abrir un archivo de registros (o una tabla de
una base de datos), ese archivo o tabla debe tener grabados sus metadatos en alguna parte para
guiar a la aplicacin en la forma de interpretar los datos que contiene. Lo tpico es que esos
metadatos se almacenen en el mismo archivo, al principio del mismo. As, el archivo
contendra dos secciones: la cabecera del archivo contendra los metadatos, y la seccin de
datos contendra los datos reales.

Las aplicaciones que crean los archivos son las encargadas de almacenar esos metadatos
en el archivo. El formato que se sigue tambin depende de la aplicacin, aunque existen
muchos estndares. Uno de los ms conocidos es el formato dbf o estndar dbf, que se impuso
a partir de la aparicin del gestor Dbase II (de Ashton Tate). Veremos con ms detalle este
formato en esta misma Ficha de clase, ms adelante.

1
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

2.) Uso de metadatos en archivos de registros.

Anexo a esta Ficha, viene el proyecto DLC10-Metadatos en el cual se muestra en forma


simple una manera de implementar archivos con metadatos. En ese proyecto, la clase Campo
representa un campo de un registro. Contiene atributos para indicar el nombre, el tipo, la
longitud (si corresponde) y un indicador para marcar a ese campo como clave. En este modelo
sencillo, se asume que el tipo de un campo puede ser int, cadena o float, y esos tipos se
representan con valores 1, 2 o 3 respectivamente en el atributo tipo. Los mtodos fRead() y
fWrite() permiten grabar un objeto de la clase en un RandomAccessFile. El mtodo copiar()
toma un objeto Campo como parmetro y copia sus valores en el objeto implcito (esto ser
necesario ms adelante, en algn proceso). El resto de los mtodos de la clase no ofrece
mayor dificultad:

import java.io.*;
public class Campo
{
private String nombre; // se asumiran no mas de 20 caracteres por nombre
private int tipo; // 0: integer - 1: real - 2: cadena
private int cantidad; // solo para cadenas!!!
private boolean esclave;

public Campo ()
{
}

public Campo (String nom, int tip, int cant, boolean es)
{
nombre = nom;
tipo = tip;
cantidad = cant;
esclave = es;
}

public String getNombre()


{
return nombre;
}

public int getTipo()


{
return tipo;
}

public int getCantidad()


{
return cantidad;
}

public boolean isClave()


{
return esclave;
}

public static int sizeOf()


{
return 40 + 4 + 4 + 1;
}

public void copiar (Campo x)

2
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

{
nombre = x.nombre;
tipo = x.tipo;
cantidad = x.cantidad;
esclave = x.esclave;
}

public void fRead (RandomAccessFile arch) throws IOException


{
nombre = Archivo.readString(arch, 20).trim();
tipo = arch.readInt();
cantidad = arch.readInt();
esclave = arch.readBoolean();
}

public void fWrite (RandomAccessFile arch) throws IOException


{
Archivo.writeString (arch, nombre, 20);
arch.writeInt(tipo);
arch.writeInt(cantidad);
arch.writeBoolean(esclave);
}
}

Se cuenta tambin con una clase Archivo, que representa un archivo de registros con
metadatos, aunque sin entrar en tanto detalle como lo realizado en el framework de
RegisterFile: slo se pretende mostrar un ejemplo simple de uso de metadatos en un archivo:

import java.io.*;
import java.util.*;
public class Archivo
{
private Campo campos;
private String nombreGeneral;
private File descArch;
private RandomAccessFile maestro;
private long iniDatos; // direccin de inicio del rea de datos en el archivo
private Campo []fields; //arreglo para guardar los metadatos

public Archivo()
{
// asumo que "nombre" viene sin extension...
this ("tabla");
}

public Archivo(String nom)


{
nombreGeneral = nom;
descArch = new File(nom + ".dat");
campos = new Campo();
}

public String getNombreGeneral()


{
return nombreGeneral;
}

public Campo [] getCampos()


{
return fields;
}

public long getIniDatos()

3
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

{
return iniDatos;
}
public void grabarMetaDato (Campo cm) throws IOException
{
cm.fWrite(maestro);
}

public void grabarMetaDato (Vector c) throws IOException


{
// se supone que el archivo est recin creado y abierto

// grabamos la cantidad de campos al inicio del archivo


maestro.writeInt(c.size());

// ahora grabamos los metadatos propiamente dichos


for(int i = 0; i<c.size(); i++)
{
grabarMetaDato((Campo)c.get(i));
}

iniDatos = maestro.getFilePointer();
}

public void crear () throws IOException


{
if(descArch.exists()) descArch.delete();
maestro = new RandomAccessFile(descArch, "rw");
}

public void abrir(String forma) throws IOException


{
if(!descArch.exists()) { throw new FileNotFoundException("No existe el archivo"); }
maestro = new RandomAccessFile(descArch, forma);

// crea el vector fields de metadatos


crearVector();

iniDatos = 4 + fields.length * Campo.sizeOf();


if(forma.compareTo("rw") == 0) maestro.seek(maestro.length());
}

public void cerrar() throws IOException


{
maestro.close();
}

public boolean eof ( ) throws IOException


{
if (maestro.getFilePointer() < maestro.length()) return false;
else return true;
}

public void grabarInt(int x) throws IOException


{
maestro.writeInt(x);
}

public void grabarFloat(float x) throws IOException


{
maestro.writeFloat(x);
}

4
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

public void grabarString(String x, int cant) throws IOException


{
writeString(maestro, x, cant);
}

public int leerInt() throws IOException


{
return maestro.readInt();
}

public float leerFloat() throws IOException


{
return maestro.readFloat();
}

public String leerString(int cant) throws IOException


{
return readString(maestro, cant).trim();
}

public static final String readString (RandomAccessFile arch, int tam)throws IOException
{
char vector[] = new char[tam];
for(int i = 0; i<tam; i++)
{
vector[i] = arch.readChar();
}
String cad = new String(vector,0,tam);
return cad;
}

public static final void writeString (RandomAccessFile arch, String cad, int tam)
throws IOException
{
int i;
char vector[] = new char[tam];
for(i=0; i<tam; i++)
{
vector[i]= ' ';
}
cad.getChars(0, cad.length(), vector, 0);
for (i=0; i<tam; i++)
{
arch.writeChar(vector[i]);
}
}

private void crearVector()throws IOException


{
// se supone que el archivo ya est abierto
int i;
int tam = Campo.sizeOf();

maestro.seek(0);
int cantcampos = maestro.readInt();

fields = new Campo[cantcampos];


for (i = 0; i < cantcampos; i++) fields[i]= new Campo();

for (i = 0; i < cantcampos; i++)


{
campos.fRead(maestro);
fields[i].copiar(campos);
}
}

5
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

De todos los atributos de la clase, los dos ms relevantes son maestro (un
RandomAccessFile) que representa al archivo en s mismo, y fields que es un arreglo de
objetos de la clase Campo, en cual se almacenar un objeto por cada campo que tenga el
registro del archivo. As, en lugar de ir a la cabecera del achivo cada vez que se quiera tomar
algn metadato, se busca ese metadato en el arreglo. Cuando el archivo se abre (ver mtodo
abrir()), lo primero que se hace es levantar los metadatos desde el archivo hacia ese arreglo, y
el mismo se deja en memoria mientras el archivo est abierto.

El mtodo crear() crea el archivo si el mismo no exista. Pero si exista, lo elimina del
disco y lo vuelve a crear. El mtodo abrir() abre el archivo si el mismo exista, y crea el
arreglo de metadatos del mismo. Si no exista, lanzar una excepcin. El file pointer del
archivo quedar ubicado al comienzo del rea de datos si el modo de apertura era "r", o al
final del archivo si el modo de apertura era "rw".

La clase contiene los ya conocidos mtodos para leer y grabar cadenas de longitud fija
en un RandomAccessFile, y el resto de los mtodos son de naturaleza trivial. La clase
Principal aporta un mtodo main con un men de opciones para crear un archivo, definir su
estructura de registro, agregar registros y mostrar el archivo. Toda la interaccin con el
archivo se regula a partir de los metadatos que el propio archivo provee:

import java.io.*;
import java.util.*;
public class Principal
{
private static Archivo archivo;
private static Campo campo;

public static void leer()


{
String nombre;
int tipo, cantidad = 0;
boolean esclave;
int resp;

System.out.print("Identificador del campo: ");


nombre = Consola.readLine();
System.out.print("Tipo (0: integer - 1: real - 2: cadena): ");
tipo = Consola.readInt();
if (tipo == 2)
{
// es tipo cadena... pedir longitud
System.out.print("Longitud: ");
cantidad = Consola.readInt();
}
System.out.print("El campo es clave del registro? (1: Si - 0: No): ");
resp = Consola.readInt();
esclave = (resp == 1)? true : false;

campo = new Campo(nombre, tipo, cantidad, esclave);


}

public static void mostrarCampo ()


{
String nombre = campo.getNombre();
int tipo = campo.getTipo(), cantidad = campo.getCantidad();
boolean esclave = campo.isClave();
String tip;

6
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

if (tipo == 0) tip = "Entero";


else if (tipo == 1) tip = "Real";
else tip = "Cadena";

System.out.println("Identificador: " + nombre);


System.out.println("Tipo: " + tip);
if (cantidad != 0) System.out.println("Longitud: " + cantidad);
System.out.println("Clave?: " + esclave);
}

public static void cargarMetaDatos () throws IOException


{
int seguir;
Vector c = new Vector();
archivo.crear();
do
{
System.out.print("Creacion de la Tabla: " + archivo.getNombreGeneral() + "\n");
System.out.print("Ingrese la informacion de los campos del registro:\n\n");
leer();
// agrego el campo a un vector...
c.add(campo);
System.out.print("Otro campo? (1: Si / 0: No): ");
seguir = Consola.readInt();
}
while (seguir == 1);

// grabamos el vector en el archivo


archivo.grabarMetaDato(c);
archivo.cerrar();
System.out.print("\n\nCreacion de estructura de tabla terminada... ");
}

public static void cargarDatos ()throws IOException


{
int i, resp, seguir, cont;
archivo.abrir("rw");

// el archivo debe estar abierto... de lo contrario el vector no existe...


Campo []fields = archivo.getCampos(); // crea un vector con los datos de los campos
int cantcampos = fields.length; // cantidad de campos!!!
cont = 0;

do
{
System.out.print("Carga de la Tabla: " + archivo.getNombreGeneral() + "\n");
System.out.print("Valores de los campos del registro nmero " + cont + ":\n");
for (i=0; i<cantcampos; i++)
{
System.out.print("\nCampo " + fields[i].getNombre() + ": ");
switch(fields[i].getTipo())
{
case 0: // int
int fieldInt = Consola.readInt();
archivo.grabarInt(fieldInt);
break;

case 1: // float
float fieldFloat = (float)Consola.readDouble();
archivo.grabarFloat(fieldFloat);
break;

case 2: // cadena
String fieldString = Consola.readLine();
archivo.grabarString(fieldString, fields[i].getCantidad());

7
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

break;
}
}
cont ++;
System.out.print("Desea cargar otro registro? (1: Si / 0: No): ");
seguir = Consola.readInt();
}
while (seguir == 1);
archivo.cerrar();
}

public static void mostrarDatos ()throws IOException


{
int i;
int resp, seguir;
int cont;
Campo []fields = archivo.getCampos();
int cantcampos = fields.length;
archivo.abrir("r");

System.out.print("Contenido de la tabla\n\n");
while (!archivo.eof())
{
for (i=0; i<cantcampos; i++)
{
System.out.print("\nCampo " + fields[i].getNombre() + ": ");
switch(fields[i].getTipo())
{
case 0: // int
int fieldInt = archivo.leerInt();
System.out.print(fieldInt);
break;

case 1: // float
float fieldFloat = archivo.leerFloat();
System.out.print(fieldFloat);
break;

case 2: // cadena
String fieldString = archivo.leerString(fields[i].getCantidad());
System.out.print(fieldString);
break;
}
}
}
archivo.cerrar();
}

public static void main (String[] args)throws IOException


{
archivo = new Archivo("Personas");
int op;

do
{
System.out.print("\n\nPrograma para manipulacion de una tabla, con metadatos\n");
System.out.print("\n1. Crear tabla");
System.out.print("\n2. Cargar tabla");
System.out.print("\n3. Mostrar tabla");
System.out.print("\n4. Salir");
System.out.print("\n\n\n\t\tElija: ");
op = Consola.readInt();
switch (op)
{

8
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

case 1: cargarMetaDatos();
break;

case 2: cargarDatos();
break;

case 3: mostrarDatos();
break;

case 4:;
}
}
while (op != 4);
System.exit(0);
}
}

3.) Anlisis general del estndar DBF.

El formato DBF es una forma de almacenar archivos en una base de datos, incluyendo
sus metadatos a modo de cabecera, que se ha hecho extremadamente popular (y se ha
convertido en un estndar universal) desde 1979 cuando fue utilizado por dBaseII.

Una base de datos es un conjunto de archivos (llamados tablas) que se relacionan de


alguna forma en base al valor de uno o ms atributos. El formato DBF permite almacenar las
tablas de una base de datos (y no realmente la base misma), en una forma que hoy es leda por
casi cualquier aplicacin de base de datos, planilla de clculo o edicin de texto de la
plataforma PC.

De hecho, el formato DBF es propio del mundo de las PC y fue pensado para
implantar de modo directo la descripcin del contenido del archivo, de forma que pueda ser
compartido con facilidad por diversas aplicaciones.

Un archivo con estructura DBF tiene tres secciones:

La cabecera (rea de metadatos)


Los registros (rea de datos)
El pie

La cabecera a su vez se divide en otras tres partes:

Metadatos para toda la tabla: Se almacenan en los primeros 32 bytes del


archivo. De esos 32 bytes, los ms importantes son los siguientes:

o Byte 0 ID
o Bytes 1 al 3 Fecha de la ltima actualizacin
o Bytes 4 al 7 Cantidad de registros que tiene el archivo
o Bytes 8 al 9 Nmero de campos que tiene el registro
o Bytes 10 al 11 Longitud de cada registro del archivo

El ID es usado de forma diferente por cada programa de gestin de base de datos.


En la prctica, podemos ignorarlo.

Todos los nmeros vienen en formato little endian, que es propio de la plataforma
PC. El formato little endian es aquel en el cual un valor de ms de un byte es

9
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

representado de forma que el byte menos significativo queda almacenado al final


del valor. En contraposicin, el formato big endian (propio de plataformas main
frame) hace que el byte ms significativo se almacene al final. Ejemplo: el
nmero 4 (en binario: 100) almacenado en una variable de tipo short se
representa con dos bytes: [00000000][00000100]. El ms significativo es el que
figura en este caso lleno de ceros, y el menos significativo es el que incuye al
100. En los formatos little y big endian, esos bytes se almacenaran as:

Little: [00000000][00000100] (menos significativo al final)


Big: [00000100][00000000] (ms significativo al final)

La fecha de ltima actualizacin se almacena en formato YMD (ao-mes-da). El


valor Y del byte 1, es el nmero de aos transcurridos desde 1900. Notar que
como cada valor lleva un nico byte, en 2156 este formato tendr problemas
similares al que tuvimos en 2000 con el Y2K...

El resto de los bytes hasta llegar al 32 se usan para almacenar valores que son
especficos de cada producto que usa el estndar. A los fines prcticos, esos bytes
pueden llenarse con ceros.

Metadatos para cada campo del archivo: Inmediatamente de los 32 bytes para
los datos de toda la tabla, siguen registros de 32 bytes cada uno, que se usan para
describir a cada campo de la tabla (es decir que si la tabla tiene, por ejemplo, 4
campos, la seccin de metadatos para campos ocupar un total de bytes 32 * 4 =
128).

En cada uno de esos registros de 32 bytes, los ms importantes son:

o Bytes 0 al 9 Nombre del campo


o Byte 11 Tipo del campo
o Byte 16 Tamao del campo
o Byte 17 Cantidad de decimales, si es aplicable

Los bytes no usados se rellenan con ceros.

El nombre de cada campo termina con cero, y el byte 10 es siempre un cero para
facilitar el manejo. Si un campo tiene menos de 10 caracteres, se rellena con
ceros a la derecha. Los nombres se almacenan en maysculas.

Los tipos de datos originales son cuatro:

C tipo caracter
N tipo numrico
D tipo fecha
L tipo lgico

Esos cuatro tipos son reconocidos por cualquier estndar, pero si el programador
desea agregar otros puede hacerlo... al precio de que con ese nuevo formato no
podr compartir sus datos!!! Existen otros tipos de datos que se han agregado al
estndar: con la F se incorpora un valor en coma flotante, con la M un campo
memo, etc.

10
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

Pie: En el formato original, el pie consta de un carcter de retorno de carro (o


sea, un 0x0D), que viene inmediatamente luego de las descripciones de los
campos.

El rea de datos o registros propiamente dichos, sigue luego del pie de la cabecera, y
desde all en adelante los registros se graban en forma consecutiva y con longitud fija.
No hay bytes de relleno entre registro y registro. El primer byte de cada registro se usa
para indicar si el registro est marcado como activo o como borrado: si est activo se
graba un blanco, y si est borrado se graba un asterisco. Luego vienen los campos,
uno tras otro. Los campos de tipo carcter se rellenan con ceros hasta ocupar la longitud
especificada en la cabecera. Los datos numricos se convierten a caracteres y se graban
como tales. El punto decimal en s mismo se graba como un caracter ms (!). Y los
datos de tipo lgico se escriben como T o F.

El pie del archivo es un caracter de finalizacin, normalmente el <Control Z> (o sea


0x1A).

11
UTN Crdoba Ingenieria en Sistemas de Informacin

Ctedra: Diseo de Lenguajes de Consulta

Bibliografa: Si bien los profesores de la ctedra preparan una serie de fichas de


consulta y gua para los temas de la asignatura, debe entenderse que para un
dominio completo de estos temas y para el desarrollo ptimo de las tareas y
ejercicios que se piden es fuertemente recomendable que los alumnos estudien e
investiguen a fondo en otras fuentes. Va para ello la siguiente bibliografa de
consulta y ampliacin de temas:

Deitel, H., Deitel, P. (2005 o posterior). "Java Cmo Programar" .


Mxico: Prentice Hall. ISBN: 970-26-0518-0 [disponible en biblioteca
del Departamento de Sistemas]

Drozdek, A. (2007). "Estructura de Datos y Algoritmos en Java".


Mxico D.F.: Thomson. ISBN: 9789706866110 [disponible en
biblioteca del Departamento de Sistemas]

Eckel, B. (2002 aunque existe edicin posterior). "Piensa en Java".


Madrid: Pearson Educacin. ISBN: 9788489660342. [disponible en
biblioteca del Departamento de Sistemas]

Horstmann, C., y Cornell G. (2000). Core Java 2 Volume I:


Fundamentals. (Disponible en espaol) Upper Saddle River:
Prentice Hall. ISBN: 84-205-4832-4 [disponible en biblioteca central]

Horstmann, C., y Cornell G. (2001). Core Java 2 Volume II:


Advanced Features. (Disponible en espaol) Palo Alto: Prentice Hall.
ISBN: 84-8322-310-4 [disponible en biblioteca central]

Langsam, Y., Augenstein, M., y Tenenbaum, A. (1997). Estructura


de Datos con C y C++ (2da. Edicin). Mxico: Prentice Hall. ISBN:
968-880-798-2 [disponible en biblioteca central]

Sedgewick, Robert (1995). Algoritmos en C++. Reading: Addison


Wesley Daz de Santos. ISBN: 978-0-201-62574-5 [disponible en
biblioteca central]

Weiss, M. A. (2000). Estructuras de Datos en Java Compatible con


Java 2. Madrid: Addison Wesley. ISBN: 84-7829-035-4 [disponible
en biblioteca central]

12

You might also like