<< >> Título

Interfaz del SFB


En este apartado se describe la interfaz del Sistema de Ficheros Básico, junto con algunos ejemplos de uso. Se comenzará mencionando algunas convenciones y estructuras comunes a toda la biblioteca, para luego pasar a presentar brevemente la interfaz funcional del SFB.

Características comunes

Tipos de datos elementales

En el fichero tipos.h se definen unos cuantos tipos de datos fundamentales que se utilizarán por todo el código de este sistema de ficheros.

Los tipos son:

typedef unsigned char BYTE;

typedef unsigned short WORD;

typedef unsigned long DWORD;

Resultados y errores

La mayoría de las funciones devuelven un int, que valdrá cero (0) si la función se ha ejecutado correctamente. Si se produce cualquier anomalía o error, todas las funciones devuelven un -1.

Algunas funciones devuelven un WORD; en caso de error, el resultado será ((WORD)-1). Igual ocurre con las funciones que devuelven un IFB (ver página ); en caso de error devuelven la constante NINGUN_IFB.

Existe una variable global llamada Error_SF, cuyo valor se corresponde con el código de error de la última función invocada. Los códigos de error están preestablecidos y se muestran en el fichero errores.h. La naturaleza y uso de Error_SF es análogo al errno de la biblioteca UNIX.

Los códigos de error son valores numéricos, pero tienen su expresión simbólica, en la forma ERR_tipo. Así, por ejemplo, existe un símbolo de nombre ERR_RANGO que se usará para indicar que algún parámetro de la última función llamada estaba fuera de rango.

Si la variable Error_SF vale cero, no se ha producido ningún error.

La macro HAY_ERROR se puede usar como una expresión booleana que es cierta si se ha producido un error. Está definida también en errores.h

El fichero básico

Un fichero básico es una secuencia de bloques de datos en disco. Un fichero básico tiene un nombre simbólico (una cadena de caracteres). Toda la información de un fichero básico se encuentra en una estructura de datos llamada bloque de fichero básico (BFB). En la implementación actual, los BFB se almacenan en forma de una tabla en los primeros bloques del disco virtual.

Índice a fichero básico: IFB

El fichero básico se identifica mediante un número, que representa su posición en la tabla de BFB. Este número identificador se llama índice a fichero básico (IFB). En sfbasico.h se define el tipo IFB, para trabajar con ficheros básicos (el tipo no es másque un unsigned short).

La mayoría de las funciones del SFB exigen como parámetro el IFB del fichero que se quiere manipular.

Operaciones con ficheros básicos

Los servicios sobre ficheros básicos consistirán en:

* crear y destruir ficheros: CreaFB(), DestruyeFB()

* añadir bloques a un fichero o truncarlo: CambiaLongitudFB()

* leer y escribir bloques de un fichero al azar: LeebloqueFB() y EscribeBloqueFB()

* obtener información del fichero: LongitudFB()

Los datos del disco se podrán leer o escribir con las funciones LeeBloqueFB() y EscribeBloqueFB(). Estas funciones trabajan con bloques completos. No está implementado el acceso con resolución de bytes, ni tampoco tendrán que implementarlo en esta práctica.

En la implementación actual, todos los ficheros tienen un tamaño fijo. De hecho, la función CambiaLongitudFB()está en blanco. Parte de su trabajo consistirá en modificar el código para permitir ficheros de cualquier tamaño, que además puedan crecer o encoger a voluntad.

Manejo del directorio

Se ofrece un par de funciones para localizar ficheros dentro del directorio:

* Búsqueda directa a partir del nombre: BuscaFB()

* Rastreo por orden de aparición en el directorio: EntradaDir()

La función BuscaFB() recibe como parámetro una cadena de caracteres y devuelve el IFB correspondiente al fichero con ese nombre, si lo encuentra. La función EntradaDir() tiene un parámetro de entrada, que es la posición dentro del directorio; el segundo parámetro es de salida y consiste en el nombre del fichero encontrado. Esta función también devuelve el IFB del fichero hallado.

Funciones de información del sistema

Se ofrecen tres funciones para obtener información sobre la configuración o el estado del sistema:

* Tamaño en bytes del bloque de datos: TamBloqueDatos()

* Espacio disponible en bytes: EspacioLibre()

* BFB disponibles: FicherosLibres()

Montaje y formato de discos

Antes de poder trabajar con un Sistema de Ficheros Básico, hay que seguir estos dos pasos:

1. Crear un disco virtual mediante FabricaDisco()

2. Dar formato de SFB al disco virtual mediante FormateaSFB()

La primera función está declarada en sffisico.h, y simula la instalación física de un disco (sin formato) en nuestro ordenador. La segunda función pertenece al módulo de SFB, está declarada en sfbasico.h y equivale al formateo del disco duro.

Un disco virtual puede formatearse tantas veces como se quiera; evidentemente, lo más normal es que se pierda la información que contenía.

Una vez que se tiene un disco formateado, se puede empezar a trabajar con él. Para ello ha de invocarse a la función MontaSFB(), pasando como parámetro la ruta del fichero UNIX deseado. Esta operación equivale al montaje de un dispositivo en UNIX. En el montaje se carga en memoria cierta información del disco (número de ficheros libres, dónde están los bloques de datos, etc.)

Las operaciones sobre ficheros básicos sólo se pueden ejecutar si hay un disco montado.

Cuando se termina de trabajar con un disco, se invoca a la función DesmontaSFB(). Las operaciones realizadas sobre un SFB deben ser permanentes: si se crea un fichero básico, se desmonta el SFB y más tarde se vuelve a montar, el fichero deberá seguir existiendo.

Ejemplo de instalación y formateo

En este ejemplo, se elabora un SFB a partir de un disco virtual con 100 bloques de 1024 bytes cada uno. El SFB tiene capacidad para 25 ficheros y maneja bloques de datos de 4096 bytes (cuatro bloques físicos):

char* args[] = { "25", "4", 0 };

FabricaDisco ("midisco",1024,100);

FormateaSFB("midisco",args);

Ejemplo de montaje y desmontaje

En este ejemplo, se usa el SFB creado anteriormente para crear un fichero de 13 bloques y escribir datos en su primer bloque de datos.

IFB ifb;

char* bufer;

MontaSFB("midisco",0);

ifb = CreaFB("mifichero",13);

bufer = (char*)malloc(TamBloqueDatos());

... rellenar bufer con algunos datos ...

EscribeFB(ifb,0,bufer);

DesmontaSFB();

Ejemplos de uso

En este apartado se muestran algunos fragmentos de código en los que se muestra el uso de los servicios del Sistema de Ficheros Básico.

Instalación y formato de un sistema

En este ejemplo, se instala y formatea una unidad de disco.

#include "sfbasico.h"

/* ... */

/* Se instala un disco de 12000x512 = 6Mbytes */

FabricaDisco ( "disco.dat", 512, 12000 );

/* Se da formato al disco con

tamaño de bloque = 2 bloques físicos(1Kbyte)

y un máximo de 500 ficheros

*/

{

const char* args[] = { "500", "2", 0 };

FormateaSFB ( "disco.dat", args );

}

/* El sistema queda ahora disponible para usos futuros */

Utilización de un disco

Este ejemplo muestra cómo se ha de montar y desmontar un disco para poder trabajar con él. Se realizan unas cuantas operaciones con algunos ficheros.

#include "sfbasico.h"

/* ... */

/* Monta el disco para trabajar con él */

MontaSFB ("disco.dat",0);

if (HAY_ERROR)

{ printf("Error con el disco\n"); exit(1); }

/* Ahora se puede trabajar con él */

/* Crea un fichero de 10 bloques y otro de 20 bloques */

CreaFB ("mi_fich",10);

/* Crea un fichero de 10 bloques y lo cambia de tamaño */

{

IFB ifb = CreaFB("otro",20);

CambiaLongitudFB(ifb,5);

}

/* Borra el fichero "mi_fich" */

{

IFB ifb = BuscaFB("mi_fich");

if (ifb==NINGUN_IFB) printf("No encontré \"mi_fich\"\n");

else BorraFB(ifb);

}

/* Desmonta el disco */

DesmontaSFB();

/* A partir de este punto, no se puede trabajar con el disco */

Acceso a bloques de datos

Este último ejemplo de uso muestra, entre otras cosas, cómo recuperar la información del superbloque para saber en este caso el tamaño en bytes del bloque de datos; y cómo hacer transferencias de datos con un fichero básico.

#include "sfbasico.h"

/* ... */

MontaSFB ("disco.dat",0);

/* Reserva espacio para escribir en un bloque */

char* bufer = (char*)malloc(TamBloqueDatos());

/* Escribe algo en el primer bloque del fichero "otro" */

IFB ifb = BuscaFB("otro");

strcpy(bufer,"Hola, mundo\n");

EscribeBloqueFB (ifb,0,bufer);

/* lee el tercer bloque del fichero "mi_fich" y lo visualiza */

ifb = BuscaFB("mi_fich");

LeeBloqueFB (ifb,2,bufer);

int total=TamBloqueDatos();

for (int i=0; i<total; i++)

{

printf ( "bufer[%d] = %c\n", i, bufer[i] );

}

/* Desmonta el disco, que ya no hace falta */

DesmontaSFB();

Prototipos de las funciones de interfaz

Formateo y montaje de discos

int FormateaSFB ( const char* nombre_fichero, const char* args[] );

int MontaSFB ( const char* nombre_fichero, int nbloques_cache );

int DesmontaSFB (void);

Información del sistema

WORD TamBloqueDatos(void);

DWORD EspacioLibre (void);

WORD FicherosLibres (void);

Creación y destrucción de ficheros

IFB CreaFB ( const char* nombre, WORD num_bloques );

int DestruyeFB ( IFB fichero );

Tamaño del fichero

WORD LongitudFB ( IFB fichero );

int CambiaLongitudFB ( IFB fichero, WORD num_bloques );

Lectura y escritura de bloques

int LeeBloqueFB ( IFB fichero, WORD num_bloque, void* bufer );

int EscribeBloqueFB ( IFB fichero, WORD num_bloque, const void* bufer );

Gestión de nombres y directorios

IFB BuscaFB ( const char* nombre );

IFB EntradaDir ( int numero_de_orden, char* nombre );


<< >> Título