All pastes #86011 Raw Edit

Anonymous

public text v1 · immutable
·published 2006-07-12 12:32 UTC
rendered paste body
unit Ficheros;

(*

Asignatura: Ficheros y Base de Datos
Curso: 2005-06
1er cuatrimetre

Práctica 1 - Ficheros

(c) 2005 Juan I. Perea - jiperea@inf.uc3m.es

Este módulo es para soporte de la práctica 1 (Ficheros).
No puede ser modificado por los alumnos bajo ningún concepto.
Es posible que se suministren pequeñas modificaciones durante el desarrollo de
la práctica.

Histórico de versiones
01.00 | 30-09-2005 | Versión inicial
01.01 | 03-10-2005 | Modificaciones reunión de profesores
01.02 | 14-10-2005 | Separación OO / no OO

*)

// ***************************************************************************

interface

  uses SysUtils;

// ***************************************************************************
// *** TamanoBloque ***
// Valor por defecto para el tamaño del bloque.

const TamanoBloque = 1024;

// ***************************************************************************
// *** TBloque ***
// Estructura formada por 'TamanoBloque' bytes que se lee y escribe en un
// fichero.
//   - Mostrar: Muestra en consola el contenido del bloque.
//   - RellenarCero: Pone a 0 todos los bytes del bloque.
//   - RellenarRandom: Rellena el bloque con valores aleatorios.

type TBloque = object
public
  data : array[0..TamanoBloque-1] of byte;
public
  procedure Mostrar ( );
  procedure RellenarCero ( );
  procedure RellenarRandom ( );
end;

function Bloque_GetByte ( var bloque : TBloque; i : Integer ) : Byte;
procedure Bloque_SetByte ( var bloque : TBloque; i : Integer; valor : Byte );
procedure Bloque_Mostrar ( var bloque : TBloque );
procedure Bloque_RellenarCero ( var bloque : TBloque );
procedure Bloque_RellenarRandom ( var bloque : TBloque );

// ***************************************************************************
// *** TFichero ***
// Clase abstracta para soporte de los demás tipos de ficheros.
// No podrá ser usada directamente.
// Encapsula la funcionalidad de ficheros de Delphi.
// Tiene funcionalidades añadidas a la de Delphi (p.ej. estadísticas).
// Las demás clases expondrán sólo cierto métodos disponible en esta clase,
// proporcionando funcionalidades reducidas que ilustren cada tipo de fichero.
// Las funciones de lectura de bloque exigen que el bloque exista.
// Las funciones de escritura extienden el tamaño del fichero si es necesario.
// Sus miembros y métodos no están visibles, a excepción de:
//   - MostrarEstadisticas: Muestra en consola la estadísticas del fichero.

type TFichero = object
protected
 // m_file : File of TBloque;
  m_file : File;
  m_error : LongInt;
  m_contDesplazar : LongInt;
  m_contLeer : LongInt;
  m_contEscribir : LongInt;
  m_contError : LongInt;
protected
  procedure Abrir ( nombre : String );
  procedure Cerrar ( );
private
  procedure TratarIOResult ( );
  procedure TratarInOutError ( func : String; e : EInOutError );
protected
  procedure IrAPosicion ( posicion : LongInt );
  function PosicionActual ( ) : LongInt;
  function FinDeFichero ( ) : Boolean;
  function NumeroDeBloques ( ) : LongInt;
  procedure LeerBloque ( var bloque : TBloque );
  procedure EscribirBloque ( const bloque : TBloque );
public
  procedure MostrarEstadisticas ( );
end;

// ***************************************************************************
// *** TFicheroSerial ***
// Clase que implementa la funcionalidad reducida de un fichero serial.
//   - Abrir: Abre el fichero en modo lectura-escritura.
//   - Cerrar: Cierra el fichero.
//   - IrAPosicionInicial: Mueve el puntero del fichero al comienzo (reset).
//   - LeerBloque: Lee el bloque situado en el puntero.
//   - EscribirBloque: Escribe un bloque sobre la posición del puntero.
// Además, hereda de TFichero:
//   - MostrarEstadisticas: Muestra en consola la estadísticas del fichero.

type TFicheroSerial= object (TFichero)
public
  procedure Abrir ( nombre : String );
  procedure Cerrar ( );
public
  procedure IrAPosicionInicial ( );
  procedure LeerBloque ( var bloque : TBloque );
  procedure EscribirBloque ( const bloque : TBloque );
end;

procedure FicheroSerial_Abrir ( var fichero : TFicheroSerial; nombre : String );
procedure FicheroSerial_Cerrar ( var fichero : TFicheroSerial );
procedure FicheroSerial_IrAPosicionInicial ( var fichero : TFicheroSerial );
procedure FicheroSerial_LeerBloque ( var fichero : TFicheroSerial; var bloque : TBloque );
procedure FicheroSerial_EscribirBloque ( var fichero : TFicheroSerial; const bloque : TBloque );
procedure FicheroSerial_MostrarEstadisticas ( var fichero : TFicheroSerial );

// ***************************************************************************
// *** TFicheroDireccionado ***
// Clase que implementa la funcionalidad reducida de un fichero direccionado.
//   - Abrir: Abre el fichero en modo lectura-escritura.
//   - Cerrar: Cierra el fichero.
//   - LeerBloque: Lee el bloque situado en una posición dada.
//   - EscribirBloque: Escribe el bloque obre una posición dada.
// Además, hereda de TFichero:
//   - MostrarEstadisticas: Muestra en consola la estadísticas del fichero.

type TFicheroDireccionado = object (TFichero)
public
  procedure Abrir ( nombre : String );
  procedure Cerrar ( );
public
  procedure LeerBloque ( posicion : LongInt; var bloque : TBloque );
  procedure EscribirBloque ( posicion : LongInt; const bloque : TBloque );
end;

procedure FicheroDireccionado_Abrir ( var fichero : TFicheroDireccionado; nombre : String );
procedure FicheroDireccionado_Cerrar ( var fichero : TFicheroDireccionado );
procedure FicheroDireccionado_LeerBloque ( var fichero : TFicheroDireccionado;
                                           posicion : LongInt; var bloque : TBloque );
procedure FicheroDireccionado_EscribirBloque ( var fichero : TFicheroDireccionado;
                                               posicion : LongInt; const bloque : TBloque );
procedure FicheroDireccionado_MostrarEstadisticas ( var fichero : TFicheroDireccionado );

// ***************************************************************************
// *** PropagarExcepciones ***

// Por defecto, no se propagan excepciones.
// Aquellos grupos que deseen recibir la excepciones en su código podrán poner
// esta variable a True.
// Esto debe hacerse asignándola desde el programa, nunca modificando aquí.

const PropagarExcepciones : Boolean = False;

// ***************************************************************************
// Funciones para soporte de este módulo.

function Hex ( n : LongInt; nc : Integer=0 ) : String;
function DescripcionIOResult ( error : Integer ) : String;
function DescripcionFileMode ( mode : Word ) : String;

// ***************************************************************************

implementation

{$IOCHECKS OFF} // Tratamiento con función IOResult
// *NO* {$IOCHECKS ON} // Tratamiento con excepciones EInOutError

// ***************************************************************************
// *** TBloque ***

procedure TBloque.Mostrar ( );
  var i, j : Integer;
  var b : Byte;
begin
  for i:=0 to (TamanoBloque div 16)-1 do begin
    Write(Hex(i*16,4),' ');
    Write('| ');
    for j:=0 to 16 do begin
      b:=data[i*16+j];
      Write(Hex(b,2),' ');
    end;
    Write('| ');
    for j:=0 to 16 do begin
      b:=data[i*16+j];
      if b>=Ord(' ')
        then Write(Chr(b))
        else Write(' ');
    end;
    WriteLn;
  end;
end;

procedure TBloque.RellenarCero ( );
  var i : LongInt;
begin
  for i:=0 to TamanoBloque-1 do begin
    data[i]:=0;
  end;
end;

procedure TBloque.RellenarRandom ( );
  var i : LongInt;
begin
  for i:=0 to TamanoBloque-1 do begin
    data[i]:=Random(256);
  end;
end;

function Bloque_GetByte ( var bloque : TBloque; i : Integer ) : Byte;
begin
  Result:=bloque.data[i];
end;

procedure Bloque_SetByte ( var bloque : TBloque; i : Integer; valor : Byte );
begin
  bloque.data[i]:=valor;
end;

procedure Bloque_Mostrar ( var bloque : TBloque );
begin
  bloque.Mostrar;
end;

procedure Bloque_RellenarCero ( var bloque : TBloque );
begin
  bloque.RellenarCero;
end;

procedure Bloque_RellenarRandom ( var bloque : TBloque );
begin
  bloque.RellenarRandom;
end;

// ***************************************************************************
// *** TFichero ***

procedure TFichero.Abrir ( nombre : String );
begin
  m_error:=0;
  m_contDesplazar:=0;
  m_contLeer:=0;
  m_contEscribir:=0;
  m_contError:=0;
  try
   // FileMode:=fmCreate+fmShareCompat;
    FileMode:=fmOpenReadWrite; // +fmShareCompat;
    AssignFile(m_file,nombre);
    if FileExists(nombre)
      then Reset(m_file,TamanoBloque)
      else Rewrite(m_file,TamanoBloque);
    TratarIOResult();
  except
    on e : EInOutError do begin
      TratarInOutError('Abrir',e);
      raise;
    end;
  end;
end;

procedure TFichero.Cerrar ( );
begin
  try
    CloseFile(m_file);
    TratarIOResult();
  except
    on e : EInOutError do begin
      TratarInOutError('Cerrar',e);
      raise;
    end;
  end;
end;

//procedure TFichero.TratarIOResult ( );
//  var e : EInOutError;
//      error : Integer;
//begin
//  error:=IOResult();
//  if error<>0 then begin
//    e:=EInOutError.Create(DescripcionIOResult(error));
//    e.ErrorCode:=error;
//    raise e;
//  end;
//end;

procedure TFichero.TratarIOResult ( );
begin
  m_error:=IOResult();
end;

procedure TFichero.TratarInOutError ( func : String; e : EInOutError );
begin
  m_error:=e.ErrorCode;
 // if m_error<>0 then begin
    Inc(m_contError);
    WriteLn;
    WriteLn('*****************************************************************************');
    WriteLn('  Error en ',func,': Error=',m_error,' ',DescripcionIOResult(m_error));
    WriteLn('*****************************************************************************');
 // end;
end;

procedure TFichero.IrAPosicion ( posicion : LongInt );
  var posicionAnterior : LongInt;
begin
  try
    posicionAnterior:=PosicionActual();
    Seek(m_file,posicion);
    TratarIOResult();
    Inc(m_contDesplazar,Abs(posicionAnterior-posicion));
  except
    on e : EInOutError do begin
      TratarInOutError('IrAPosicion',e);
      raise;
    end;
  end;
end;

function TFichero.PosicionActual ( ) : LongInt;
begin
  try
    Result:=FilePos(m_file);
    TratarIOResult();
  except
    on e : EInOutError do begin
      TratarInOutError('PosicionActual',e);
      raise;
    end;
  end;
end;

function TFichero.FinDeFichero ( ) : Boolean;
begin
  try
    Result:=Eof(m_file);
    TratarIOResult();
  except
    on e : EInOutError do begin
      TratarInOutError('FinDeFichero',e);
      raise;
    end;
  end;
end;

function TFichero.NumeroDeBloques ( ) : LongInt;
begin
  try
    Result:=FileSize(m_file);
    TratarIOResult();
  except
    on e : EInOutError do begin
      TratarInOutError('NumeroDeBloques',e);
      raise;
    end;
  end;
end;

procedure TFichero.LeerBloque ( var bloque : TBloque );
begin
  try
    BlockRead(m_file,bloque,1);
    TratarIOResult();
    Inc(m_contLeer);
  except
    on e : EInOutError do begin
      TratarInOutError('LeerBloque',e);
      raise;
    end;
  end;
end;

procedure TFichero.EscribirBloque ( const bloque : TBloque );
begin
  try
    BlockWrite(m_file,bloque,1);
    TratarIOResult();
    Inc(m_contEscribir);
  except
    on e : EInOutError do begin
      TratarInOutError('EscribirBloque',e);
      raise;
    end;
  end;
end;

procedure TFichero.MostrarEstadisticas ( );
begin
  WriteLn;
  WriteLn('*****************************************************************************');
  WriteLn(' Nombre        : ',TFileRec(m_file).Name);
  WriteLn(' Modo          : ',DescripcionFileMode(TFileRec(m_file).Mode));
  WriteLn(' N. bloques    : ',NumeroDeBloques():4);
  WriteLn('Estadisticas del fichero');
  WriteLn(' N. desplazam. : ',m_contDesplazar:4);
  WriteLn(' N. lecturas   : ',m_contLeer:4);
  WriteLn(' N. escrituras : ',m_contEscribir:4);
  WriteLn(' N. errores    : ',m_contError:4);
  WriteLn('*****************************************************************************');
  WriteLn;
end;

// ***************************************************************************
// *** TFicheroSerial ***

procedure TFicheroSerial.Abrir ( nombre : String );
begin
  try
    inherited Abrir(nombre);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroSerial.Cerrar ( );
begin
  try
    inherited Cerrar();
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroSerial.IrAPosicionInicial ( );
begin
  try
    inherited IrAPosicion(0);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroSerial.LeerBloque ( var bloque : TBloque );
begin
  try
   // bloque.RellenarRandom();
    inherited LeerBloque(bloque);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroSerial.EscribirBloque ( const bloque : TBloque );
begin
  try
    inherited EscribirBloque(bloque);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure FicheroSerial_Abrir ( var fichero : TFicheroSerial; nombre : String );
begin
  fichero.Abrir(nombre);
end;

procedure FicheroSerial_Cerrar ( var fichero : TFicheroSerial );
begin
  fichero.Cerrar();
end;

procedure FicheroSerial_IrAPosicionInicial ( var fichero : TFicheroSerial );
begin
  fichero.IrAPosicionInicial();
end;

procedure FicheroSerial_LeerBloque ( var fichero : TFicheroSerial; var bloque : TBloque );
begin
  fichero.LeerBloque(bloque);
end;

procedure FicheroSerial_EscribirBloque ( var fichero : TFicheroSerial; const bloque : TBloque );
begin
  fichero.EscribirBloque(bloque);
end;

procedure FicheroSerial_MostrarEstadisticas ( var fichero : TFicheroSerial );
begin
end;

(*
// ***************************************************************************
// *** TFicheroSecuencial ***

procedure TFicheroSecuencial.MoverPosicion ( posicionRelativa : Longint );
begin
  try
    IrAPosicion(PosicionActual()+posicionRelativa);
  except
  end;
end;

*)

// ***************************************************************************

// ***************************************************************************
// *** TFicheroDireccionado ***

procedure TFicheroDireccionado.Abrir ( nombre : String );
begin
  try
    inherited Abrir(nombre);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroDireccionado.Cerrar ( );
begin
  try
    inherited Cerrar();
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroDireccionado.LeerBloque ( posicion : LongInt; var bloque : TBloque );
begin
  try
   // bloque.RellenarRandom();
    IrAPosicion(posicion);
    inherited LeerBloque(bloque);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure TFicheroDireccionado.EscribirBloque ( posicion : LongInt; const bloque : TBloque );
begin
  try
    IrAPosicion(posicion);
    inherited EscribirBloque(bloque);
  except
    if PropagarExcepciones then raise;
  end;
end;

procedure FicheroDireccionado_Abrir ( var fichero : TFicheroDireccionado; nombre : String );
begin
  fichero.Abrir(nombre);
end;

procedure FicheroDireccionado_Cerrar ( var fichero : TFicheroDireccionado );
begin
  fichero.Cerrar();
end;

procedure FicheroDireccionado_LeerBloque ( var fichero : TFicheroDireccionado;
                                           posicion : LongInt; var bloque : TBloque );
begin
  fichero.LeerBloque(posicion,bloque);
end;

procedure FicheroDireccionado_EscribirBloque ( var fichero : TFicheroDireccionado;
                                               posicion : LongInt; const bloque : TBloque );
begin
  fichero.EscribirBloque(posicion,bloque);
end;

procedure FicheroDireccionado_MostrarEstadisticas ( var fichero : TFicheroDireccionado );
begin
  fichero.MostrarEstadisticas();
end;

// ***************************************************************************

function Hex ( n : LongInt; nc : Integer=0 ) : String;
  var i : LongInt;
  var c : Byte;
begin
 // Result:=StringOfChar('0',nc);
  Result:='';
  i:=1;
  while (i<=nc) or (n>0) do begin
    c:=n mod 16;
    n:=n div 16;
    if c<10
      then Result:=Chr(Ord('0')+c)+Result
      else Result:=Chr(Ord('a')+c-10)+Result;
    Inc(i);
  end;
end;

function DescripcionIOResult ( error : Integer ) : String;
begin
  case error of
    100 : Result:='End of File';
    101 : Result:='Disk Full';
    102 : Result:='File variable not assigned';
    103 : Result:='File not open';
    104 : Result:='File not open for input';
    105 : Result:='File not open for output';
    106 : Result:='Error in formatted input';
    107 : Result:='File already open';
  end;
end;

function DescripcionFileMode ( mode : Word ) : String;
begin
  case mode of
    fmClosed : Result:='Cerrado';
    fmInput : Result:='Entrada';
    fmOutput : Result:='Salida';
    fmInOut : Result:='Entrada/Salida';
  end;
end;

// ***************************************************************************

end.