• Domingo 17 de Noviembre de 2024, 16:32

Autor Tema:  Archivos tipo file con registros de longitud variable  (Leído 5344 veces)

simchgab

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Archivos tipo file con registros de longitud variable
« en: Miércoles 15 de Mayo de 2013, 16:06 »
0
Hola chicos/as como andan?
Queria consultarles si tienen algun recurso, que explique lo mejor posible el manejo de archivos con registros de longitud variable, y con el manejo de bloques.
Ya que tengo un libro pero la verdad que no explica demasiado bien. Y los ayudantes en la materia son un desastre.
por ahora lo que entiendo, es que no se utiliza una estructura (no se declaran los tipos) como en los de longitud fija, si no que se utilizan bloques de x tamaño de byte, donde cada campo se delimita por un caracter x y cada registro por un caracter y, les dejo el codigo de un ejemplo, o un intento de explicacion de la cursada, lo cual no entiendo para que joden tanto en materias anteriores con la legibilidad del codigo y la correcta indentacion si estos son un desastre :S

{Manejo de archivo secuencial de personas, con registros de longitud variable.

Los comentarios y salidas en pantalla se escriben sin acentos para se vean
siempre igual en todo entorno.

Autor: Arturo Servetto}

Interface

Const
     TamBloque = 64;
     CapacBloque = TamBloque-SizeOf(Word);
     PorcCarga = 0.9; {Porcentaje de carga de los bloques (se deja espacio
     disponible por si se actualizan registros aumentando su longitud, para no
     tener que cambiarlos de bloque)}
     PersonaFin = 'fin'; {para representar el fin del archivo}

Type
    tNombre = String[31]; {para manejar personas en memoria}
    tBloque = Record
            cantRegs: Word; {cantidad actual de registros en el bloque}
            contenido: Array[1..CapacBloque] of Byte
            end;

    Modo = (esc, lecOesc); {modo de apertura del archivo: esc(ritura), o
    lec(tura)Oesc(ritura)}

    tPersonas = Record
              arch: File of tBloque; {archivo de personas}
              espLibre: File of Word; {archivo de control de bytes libres por
              bloque del archivo de personas}
              m: Modo; {modo en que esta abierto el archivo}
              bloque: tBloque; {ultimo bloque leido de personas}
              iBloque: Word; {indice de posicion dentro del bloque}
              espLibreBloque: Word
              end;

Procedure Abrir(var pp: tPersonas);

Procedure Cerrar(var pp: tPersonas);

Procedure Crear(var pp: tPersonas);

Procedure Cargar(var pp: tPersonas; p: tNombre); {alta secuencial}

Procedure Agregar(var pp: tPersonas; p: tNombre); {alta con busqueda de espacio}
{Dada la simplicidad del problema, no se verifica la unicidad de los nombres}

Procedure Primero(var pp: tPersonas; var p: tNombre); {primer registro del
archivo}

Procedure Siguiente(var pp: tPersonas; var p: tNombre; var inicio: Boolean);
{recuperacion secuencial - inicio True implica primer registro del bloque}

Procedure InfoBloque(var pp: tPersonas; var info: String);

Procedure Obtener(var pp: tPersonas; pb: tNombre; var result: Boolean);
{Se busca pb en el archivo con resultado True si se encuentra}

Procedure Eliminar(var pp: tPersonas; p: tNombre; var result: Boolean);
{result falso implica que no se encuentra la persona}

Procedure Modificar(var pp: tPersonas; pb: tNombre; var p: tNombre;
var result: Boolean);
{result falso implica que no se encuentra la persona}

(******************************************************************************)

Implementation

Procedure Abrir(var pp: tPersonas);
Begin
With pp do begin Reset(arch); Reset(espLibre); m:=lecOesc end
end;

Procedure Cerrar(var pp: tPersonas);
Begin
With pp do begin
     If m=esc {si el archivo se abrio para cargarlo}
     then If pp.bloque.cantRegs>0 {si el ult. bloque tiene contenido no grabado}
          then With pp do begin  {se escribe el ultimo bloque}
               Write(arch, bloque); Write(espLibre, espLibreBloque)
               end;
     Close(arch); Close(espLibre)
     end
end;

Procedure Crear(var pp: tPersonas);
{Inicializa la estructura y crea los archivos. Los archivos deben estar
asignados}
Begin
With pp do begin
     Rewrite(arch); Rewrite(espLibre); m:=esc;
     bloque.cantRegs:=0;
     iBloque:=1;
     espLibreBloque:=CapacBloque
     end
end;

Procedure Cargar(var pp: tPersonas; p: tNombre);
{Agrega una persona en el bloque actual o comienza un nuevo bloque al final del
archivo (no se busca espacio libre). El bloque actual es el ultimo del archivo}
Var
   tamReg: Byte;
   disponibles: Integer; {bytes disponibles en un bloque, sin exceder el porc.
   de carga}
Begin
tamReg:=Length(p)+1; {longitud del nombre mas un byte por el prefijo de longitud}
disponibles:=pp.espLibreBloque-Round((1-PorcCarga)*CapacBloque);
If tamReg>disponibles
then {el registro sobrecarga al bloque actual}
     With pp do begin
     Write(arch, bloque); Write(espLibre, espLibreBloque);
     bloque.cantRegs:=0; espLibreBloque:=CapacBloque;
     iBloque:=1;
     end;
With pp do begin {se agrega el registro al bloque actual}
     Move(p, bloque.contenido[iBloque], tamReg); {movemos de una direccion de memoria a otra direccion de memoria}
     Inc(iBloque, tamReg);
     Inc(bloque.cantRegs);
     Dec(espLibreBloque, tamReg)
     end
end;

Procedure Agregar(var pp: tPersonas; p: tNombre);
{Agrega una persona en el primer bloque que tenga espacio o, si no hay ninguno,
en un bloque nuevo al final del archivo}
Var
   tamReg: Byte;
   libres: Word;
   disponibles: Integer;
Begin
With pp do begin
Seek(espLibre, 0);
tamReg:=Length(p)+1;
Repeat
Read(espLibre, libres);
disponibles:=libres-Round((1-PorcCarga)*CapacBloque) {bytes libres menos los que
no se pueden usar para altas}
until eof(espLibre) or (disponibles>=tamReg);
If tamReg>disponibles
then begin {hay que agregar un nuevo bloque al final del archivo}
     bloque.cantRegs:=0;
     libres:=CapacBloque;
     iBloque:=1;
     Seek(arch, FileSize(arch))
     end
else Begin
     Seek(arch, FilePos(espLibre)-1); Read(arch, bloque);
     iBloque:=CapacBloque-libres+1;
     Seek(arch, FilePos(espLibre)-1); seek(espLibre, FilePos(espLibre)-1)
     end;
Move(p, bloque.contenido[iBloque], tamReg);
Inc(bloque.cantRegs);
Dec(libres,tamReg);
Write(arch, bloque); Write(espLibre, libres)
end
end;

Procedure Primero(var pp: tPersonas; var p: tNombre); {inicio de secuencia}
{Devuelve el primer registro de persona. El archivo debe tener al menos una
persona}
Var
   tamReg: Byte;
Begin
With pp do begin
Seek(arch, 0); Read(arch, bloque); tamReg:=bloque.contenido[1]+1;
Move(bloque.contenido[1], p, tamReg);
iBloque:=tamReg+1; Seek(espLibre, 0); Read(espLibre, espLibreBloque)
end
end;

Procedure Siguiente(var pp: tPersonas; var p: tNombre; var inicio: Boolean);
{Devuelve la siguiente persona a partir de la ultima devuelta, o PersonaFin si
la ultima devuelta fue la ultima del archivo}
Var
   tamReg: Byte;
Begin
With pp do begin
If (iBloque>CapacBloque-espLibreBloque) and (not eof(arch))
then begin {no hay más registros en el bloque}
     Read(arch, bloque); iBloque:=1; Read(espLibre, espLibreBloque);
     inicio:=True
     end
else inicio:=False;
If iBloque<CapacBloque-espLibreBloque
then begin
     tamReg:=bloque.contenido[iBloque]+1;
     Move(bloque.contenido[iBloque], p, tamReg);
     Inc(iBloque, tamReg)
     end
else p:=PersonaFin
end
end;

Procedure InfoBloque(var pp: tPersonas; var info: String);
Var nb, crr, bbll: String[5]; {numero de bloque, cantidad de registros, bytes
libres}
Begin
Str(FilePos(pp.arch)-1, nb);
Str(pp.bloque.cantRegs, crr);
Str(pp.espLibreBloque, bbll);
info:='Bloque '+nb+': '+crr+' personas - '+bbll+' bytes libres'
end;

Procedure Obtener(var pp: tPersonas; pb: tNombre; var result: Boolean);
{Se busca pb en el archivo con resultado True si se encuentra}
var inicio: Boolean; p: tNombre;
Begin
With pp do begin
     Primero(pp, p);
     While (p<>PersonaFin) and (p<>pb) do Siguiente(pp, p, inicio);
     If p=pb then result:=True else result:=False
     end
end;

Procedure Eliminar(var pp: tPersonas; p: tNombre; var result: Boolean);
{result falso implica que no se encuentra la persona}
var resObt: Boolean; resto: Word; tamReg: Byte;
Begin
Obtener(pp, p, resObt);
If resObt
then With pp do begin {se encuentra a la persona}
             resto:=CapacBloque-espLibreBloque-iBloque+1;
             tamReg:=Length(p)+1;
             If resto>0 then
               {si no esta al final se corren a izq. las siguientes}
               Move(bloque.contenido[iBloque], bloque.contenido[iBloque-tamReg], resto);
             Dec(bloque.cantRegs); Inc(espLibreBloque, tamReg);
             Seek(arch, FilePos(arch)-1); Write(arch, bloque);
             Seek(espLibre, FilePos(espLibre)-1);
             Write(espLibre, espLibreBloque);
             result:=True
             end
else result:=False
end;

Procedure Modificar(var pp: tPersonas; pb: tNombre; var p: tNombre; var result: Boolean);
var resObt: Boolean;  resto: Word; tamReg: Byte;
Begin
Obtener(pp, pb, resObt);
If resObt
        then with pp do begin
             resto:=CapacBloque-espLibreBloque-iBloque+1;
             tamReg:=Length(pb)+1;
             If resto>0 {si no esta al final se corren a izq. las siguientes}
             then Move(bloque.contenido[iBloque],
                  bloque.contenido[iBloque-tamReg], resto);
             Inc(espLibreBloque, tamReg);
             iBloque:=CapacBloque-espLibreBloque+1;
             tamReg:=Length(p)+1;
             If tamReg>espLibreBloque {en este caso no se considera el factor de
             carga}
             then begin {no entra en el bloque actual; se graba el actual y el
             valor modificado se trata como un alta}
                Seek(arch, FilePos(arch)-1); Write(arch, bloque);
                Seek(espLibre, FilePos(espLibre)-1);
                Write(espLibre, espLibreBloque);
                Agregar(pp, p)
                end
             else begin {se agrega el valor modificado al final del bloque}
                Move(p, bloque.contenido[iBloque], tamreg);
                Dec(espLibreBloque, tamReg);
                Seek(arch, FilePos(arch)-1); Write(arch, bloque);
                Seek(espLibre, FilePos(espLibre)-1);
                Write(espLibre, espLibreBloque)
                end;
             result:=True
             end
        else result:=False
end;


Desde ya muchisimas gracias

raul666

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Re:Archivos tipo file con registros de longitud variable
« Respuesta #1 en: Jueves 16 de Mayo de 2013, 02:33 »
0
¡¡Hola que tal compañer@ de penurias!!

Para ayudarte te dejo algo que publicaron los chicos de La Fuente, el Centro de Estudiantes, hace unos años ya. Están en mediafire pero son PDFs livianitos.

http://lafuenteunlp.blogspot.com.ar/2011/06/manejo-de-archivos-con-longitud.html

Lo que contiene estos pdfs son precisamente algunos procedimientos de los que publica Arturo pero los chicos se han tomado el laburo de comentarlos línea a línea.

Espero te sirvan para arrancar.

Saludos

Raúl Campanelli.. Turno Mañana: IBBDD, AYED, Lenguaje C.
« última modificación: Martes 22 de Abril de 2014, 01:14 por raul666 »