Fundamentacion TAD Diseño MiniFS


Implementación Mini File System (MiniFS)
 TAD
































INTRODUCCIÓN – FUNDAMENTACIÓN:



En esta primera fase de análisis del problema planteado (construir un simulador del administrador de archivos y directorios de un sistema operativo similar a MS-DOS), nos hemos concentrado en lograr una correcta comprensión de dicho problema. Para ello, y aplicando el principio de separación de intereses, comenzamos descomponiendo el problema a resolver en problemas más pequeños; además, aplicando el principio de abstracción, hemos individualizado los objetos de la realidad que nos interesan, ya que a partir del análisis del comportamiento de estos, podremos traducir dicho comportamiento en las operaciones que nos permitan su manipulación.

Dentro de las distintas categorías de tipos abstractos de datos (TAD), vamos a trabajar con colecciones, que son las que representan agrupaciones de elementos. Y dentro de ellas, utilizaremos las que necesitan clave de identificación, o sea diccionario, pues una de las condiciones del problema, es que no puede haber dos archivos o dos directorios con el mismo nombre.

La estructura ABB (Árbol Binario de Búsqueda) suele ser una de las más apropiadas para representar un diccionario, dado que es idónea para elementos que poseen una clave que los identifica, como es nuestro caso; siendo más eficiente esta estructura cuando interesa recorrer los elementos del diccionario ordenados por clave de menor a mayor.



DISEÑO:


1. TAD: Diccionario


1.1 Definición de clave: La clave en este caso, es una cadena de caracteres (string) que corresponde al nombre de archivos y directorios.


1.2 Definición de tipo elemento:



        1.2.1 ARCHIVO: El tipo de dato es una estructura que contiene: campos para el nombre, texto, atributo, puntero a nodo archivo derecho, puntero a nodo archivo izquierdo.


        1.2.2 DIRECTORIO: El tipo de dato es una estructura que contiene un campo para nombre, puntero a la estructura nodo directorio que se va a llamar padre, puntero a nodo directorio izquierdo, puntero al nodo directorio derecho, puntero a un nodo hijo de directorio, y otro puntero al nodo primer hijo de archivos.


        1.2.3 SISTEMA: Nuestro sistema (RAIZ) contiene los mismos campos que tiene DIRECTORIO. Este es el único directorio que no tiene padre.


1.3 Operaciones de diccionario:


crear_diccionario: → Diccionario

Crea un diccionario vacío


buscar_elemento: Diccionario x clave → Boolean

Determina si en el diccionario existe un elemento con la clave especificada


agregar: Diccionario x tipo_elemento → Diccionario

Inserta un elemento de tipo elemento en el diccionario.

Precondición: el elemento a insertar no es miembro del diccionario

buscar: Diccionario x clave → tipo_elemento

Dada la clave de un elemento devuelve el elemento con dicha clave

Precondición: el elemento es miembro del diccionario.


modificar: Diccionario x tipo_elemento → Diccionario

Sustituye el viejo elemento de tipo_elemento en el diccionario por el nuevo

Precondición: el elemento a sustituir es miembro del diccionario.


borrar: Diccionario x clave → Diccionario

Dada la clave de un elemento lo borra del diccionario

Precondición: el elemento es miembro del diccionario.



2. SISTEMA: filesystem

2.1 Definición:


struct NODO_Raiz{

struct NODO_Raiz *izq;

struct NODO_Raiz *der;

struct NODO_Raiz *primer_hijo_dir;

struct NODO_Raiz *primer_hijo_file;

char Nombre[16];

};

typedef NODO_Raiz * filesystem;




2.2 Operaciones de sistema:


crearsistema: → filesystem

Crea un nuevo sistema (RAIZ).

                        Precondición: no debe existir otra raíz.


  • void crearsistema (filesystem &f);


destruirsistema: filesystem →{}

Elimina el sistema, desde la RAIZ recursivamente recorriendo el árbol de

directorios y de archivos, liberando la memoria usada.

Precondición: deben existir estructuras que constituyen el filesystem.


  • void destruirsistema (filesystem &f);


createfile: filesystem x nombre →filesystem

Modifica el filesystem, creando un nuevo archivo

Precondición: debe existir el sistema.


  • void createfile (filesystem &f, char *n); n contiene el nombre de archivo


delete: filesystem x nombre  → filesystem

            Modifica el sistema eliminando un archivo.

Precondición: debe existir el sistema.


  • void delete (filesystem &f, char *n) n contiene el nombre de archivo a borrar.


rmkdir: filesystem x nombre → filesystem

Crea un nuevo directorio en el sistema, modifica el sistema.

Precondición: debe existir el sistema.


  • void mkdir (filesystem &f, char *n); n es el nombre del directorio que vamos a crear.


rmdir: filesystem x nombre → filesystem

Elimina un directorio del sistema. Modifica el sistema.

                        Precondición: debe existir el directorio.


  • void rmdir (filesystem &f, char *n); n contiene el nombre del directorio


dir: filesystem x parametro → E/S

                        Devuelve el directorio actual. No modifica el sistema.

                        Precondición: debe existir el directorio.


  • void dir (filesystem f, char *n); n 3 posibilidades: (argumento nulo), (..) o (nombre del directorio)

cd: filesystem x parametro → filesystem

Regresa al directorio RAIZ desde cualquier directorio. No modifica el sistema.

                        Permite desplazarse al directorio indicado.

Permite ir al directorio padre del directorio actual. Esta función modifica el sistema.

Precondición: debe existir RAIZ, debe existir el directorio. No debe ser el directorio RAIZ. En caso de serlo, no se cambiará de directorio.

  • void cd (filesystem f, char *n); n 3 posibilidades: (RAIZ), (..) o (nombre del directorio)


attrib: filesystem x nombre x attrib → filesystem

Cambia permiso de escritura/lectura a los archivos modificando la estructura del

filesystem. La función modifica n para separar en tokens.

Precondición: el modo debe ser diferente al actual.


  • void attrib (filesystem &f, char *n); n contiene 2 tokens: el nombre del archivo y el modificador (+w o -w).


it: filesystem x nombre x texto→ filesystem

Agrega texto al comienzo del archivo modificando la estructura del filesystem.

La función modifica n para separar en tokens.

Precondición: debe existir archivo en el directorio actual.


  • void it (filesystem &f, char *n); n contiene 2 tokens. que son el nombre del archivo y el texto.


type: filesystem x nombre → E/S

                        Imprime contenido del archivo. No modifica el sistema.

Precondición: debe existir el archivo.


  • void type (filesystem &f, char *n); n contiene el nombre del archivo.



3. DIRECTORIOS:

3.1 Definición:


struct NODO_DIR{

struct NODO_DIR *padre;

struct NODO_DIR *izq;

struct NODO_DIR *der;

struct NODO_DIR *primer_hijo_dir;

struct NODO_FILE *primer_hijo_file;

char Nombre[16]; //15 caracteres + \0 final

};

typedef NODO_DIR * abb_directorio;


3.2 Operaciones sobre directorios:


mkdir: abb_directorio x nombre → abb_directorio

                        Crea un nuevo subdirectorio (vacío) dentro del directorio actual.

Precondición: no pueden existir dos directorios con el mismo nombre en el mismo nivel de jerarquía. No se puede utilizar el nombre RAIZ. El nombre deberá tener un máximo de 15 caracteres (alfanumérico).


  • void mkdir (abb_directorio&d, char *n);


rmdir: abb_directorio x nombre → abb_directorio

Elimina un subdirectorio hijo del directorio actual. Al eliminarlo, se elimina también todos sus subdirectorios y los correspondientes archivos.

Precondición: debe existir el directorio que se va a borrar.


  • void rmdir (abb_directorio &d, char *n);


cd: abb_directorio x nombre → abb_directorio

Se desplaza un nivel en la jerarquía de directorios. No modifica el sistema.

Precondición: debe existir un directorio con ese nombre.

  • void cd (abb_directorio d, char *n);


cd..: abb_directorio → abb_directorio

Sube un nivel en la jerarquía de directorios. No modifica el sistema.

Precondición: debe existir un directorio con ese nombre.


  • void cd(abb_directorio d, char *n);


cd RAIZ: abb_directorio → abb_directorio

Regresa al directorio RAIZ desde cualquier directorio. No modifica el sistema.

                        Precondición: debe existir RAIZ.


  • void cd (abb_directorio d, char *n);


dir: abb_directorio x nombre → E/S

Lista el contenido del directorio actual, ya sean subdirectorios o archivos, sin mostrar el contenido de sus subdirectorios. Primero se listan los archivos en orden alfabético creciente y luego los directorios también en orden alfabético. No modifica el sistema.

Precondición: debe existir el directorio del que se quiere listar su contenido. En caso que no exista, se indica con un mensaje.


  • void dir (abb_directorio d, char *n)


dir directorio: abb_directorio x nombre → E/S

Muestra el contenido del directorio indicado.

Precondición: debe ser subdirectorio del directorio actual.


  • void dir (abb_directorio d, char *n)


dir ..: abb_directorio → E/S

                        Muestra el contenido del directorio padre del directorio actual. No modifica el sistema.

Precondición: debe existir el directorio del que se quiere mostrar el contenido. En caso que no exista (RAIZ), se indica con un mensaje.


  • void dir (abb_directorio d, char *n);



4. ARCHIVOS:

4.1 Definición:


struct NODO_FILE{

struct NODO_FILE *izq;

struct NODO_FILE *der;

char Nombre[20];

char *Texto;

bool SoloLectura;

};

typedef NODO_FILE *abb_archivo;



4.2 Operaciones sobre archivos:


createfile: abb_archivo x nombre → abb_archivo

Crea un nuevo archivo en el directorio actual.

Precondición: debe existir el directorio. El contenido será vacío. Todo archivo que se crea será de lectura/escritura. No puede llamarse igual que otro archivo que se encuentre en el mismo nivel de directorios.


  • void _createfile (abb_archivo &a, char *n)

delete: abb_archivo x nombre → abb_archivo

            Elimina un archivo del directorio actual.

Precondición: debe existir archivo. No puede ser solo lectura.


  • void _delete (abb_archivo &a, char *n)

attrib: abb_archivo x nombre x modificador  → abb_archivo

Cambia los atributos de un archivo que pertenece al directorio actual. Modificador de lectura y escritura.

Precondición: debe existir archivo con el nombre indicado. El modo debe ser diferente al actual.


  • void attrib( abb_archivo &a, char *n)


it: abb_archivo x nombre x texto   →  abb_archivo

Agrega un texto al comienzo del archivo con el nombre dado.

Precondición: debe respetar el largo total. Debe existir el archivo en el directorio actual. Solo se ingresa el texto si tiene permiso de escritura.


  • void it (abb_archivo &a, char *n)


type: abb_archivo x nombre →    E/S

Imprime el contenido del archivo, independientemente de su condición de lectura/escritura.

Precondición: debe existir el archivo.


  • void type (abb_archivo &a, char *n)



4. INTERFAZ DE USUARIO:


Está compuesta por una aplicación de consola simulando un intérprete de comandos tipo MS-DOS.

char *n en nuestro programa definimos: char comando[128];

Comando es una variable de tipo string que en principio contiene todo lo tipeado en la consola hasta apretar enter; luego en "evalua" se le quita el primer token si coincide con alguna "acción", ese nuevo comando (más corto) sólo contiene los argumentos que se le pasan a la función correspondiente a esa acción; dentro de esas funciones, eventualmente (attrib, it), se sigue dividiendo más en tokens.


Se evalúa lo tipeado por el usuario usando la función evalua:


bool evalua (char *comando, const char *accion, void (*proc)(char *))

  • proc es un puntero a función, según la acción a realizar se pasa como argumento la función que la realiza.

  • const char *accion – se usa const porque los string literals no deben ser modificados, esta "const" impide que la función modifique esa parte de la memoria.































ċ
main.cpp
(2k)
Andrés Franchi,
23 nov. 2015 5:23
ċ
miniFS.cpp
(29k)
Andrés Franchi,
23 nov. 2015 5:23
ċ
miniFS.h
(2k)
Andrés Franchi,
23 nov. 2015 5:23
Comments