Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Educativo
Jos Baltasar Garca Perez-Schofield
Manuel Prez Cota
Departamento de Lenguajes y Sistemas Informticos
Universidad de Vigo
{jbgarcia; mpcota}@uvigo.es {URL: http://www.lsi.uvigo.es}
Resumen
En este artculo abordamos la problemtica de la enseanza del uso de ficheros
en un lenguaje Orientado a Objetos como el C++ directamente relacionado con este
paradigma de programacin. Como podemos encontrar en la bibliografa, existen
mltiples sistemas de acceso a ficheros (casi uno por lenguaje), y casi ninguno se
encuentra integrado de una forma que podamos decir coherente. Aqu intentamos, pues,
dar una solucin al problema docente que implica dar una perspectiva real al alumno
de lo que sucede en el manejo de los ficheros dentro del lenguaje de programacin
C++. Veremos como afecta el cambio de plataforma a los programas realizados segn
el estndar (supuestamente portable), y, finalmente, una solucin que hace ms
transparente su entendimiento.
Introduccin.
En el lenguaje C++, muchas veces encontramos sutiles diferencias entre
distintas implementaciones del estndar ANSI; estas diferencias hacen que programas
escritos mediante herramientas ANSI, en principio, portables a nivel de cdigo fuente
(compilables en cualquier plataforma) no lo sean en realidad. Este problema se trata en
la primera parte del artculo, mientras que en las siguientes secciones se desarrollarn
unas clases de ejemplo de tratamiento de ficheros, diseadas para sustituir a las fstream,
las clases que acompaan a la distribucin ANSI de C++ [3][4], para manejo de
ficheros. El objetivo de este artculo es, finalmente, mostrar unas clases que
proporcionen un acceso coherente segn la OOP a ficheros, y que, a la vez, sean
portables segn el estndar ANSI.
El estndar C++
Existen ciertos aspectos del lenguaje estndar[6] C++ que no estn
completamente definidos. Es de notar, por ejemplo, el uso de lo que en UNIX son
llamadas al sistema como open(), read(), write() en la gestin de archivos; stas
funciones se mantienen en C++ (al ser un superconjunto de C). En principio, no son
estndar, si bien existen en todos los compiladores (podramos decir que son estndar de
facto), puesto que en otro caso, una gran mayora de programas escritos en C (e incluso
en C++), no compilaran en absoluto, al utilizar estas llamadas. Las funciones que se
pensaron que sustituiran a las llamadas al sistema fueron fopen(), fread(), fwrite(),
fclose()... etc. En C++, se crearon las clases streams para recubrir estas llamadas [1].
Al no formar estas llamadas parte del estndar, se dan casos curiosos, que
eliminan la portabilidad, a nivel de cdigo fuente, del C++, como el siguiente ejemplo:
las cabeceras que es necesario incluir en un programa C++ para UNIX para acceder a
las llamadas al sistema de ficheros son:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
alguna forma organizada, aunque, por supuesto, para hablar de una base de datos, sera
necesaria la agregacin de ms capas de software.
La clase regdirect aade un nivel ms de abstraccin, grabando siempre lo que a
un nivel fsico seran bloques de bytes de tamao fijo, y que a este nivel son objetos,
que hacen el papel del registro clsico.
Consideraciones sobre estas clases de recubrimiento de acceso a ficheros.
Un aspecto importante, que no presentan las clases stream de C++, ni las clases
de Java, es el manejo de objetos desde un punto de vista de homogeneidad respecto al
resto de los tipos de datos.
Aunque en principio debiera ser sencillo poder grabar el estado (es decir, lo que
en C++ se correspondera con la instancia) de un objeto, no lo es tanto, cuando nos
enfrentamos al problema de que C++ no ofrece ningn mecanismo estndar para
obtener ese tipo de informacin de un objeto. Es decir, no disponemos de la capacidad
de metainformacin[7] acerca de un objeto (nombre de la clase, tamao etc.). Por
supuesto, esto puede implementarse, aunque conlleva ciertos problemas que se
comentarn ms adelante. Aqu se ha resuelto de la siguiente forma: se ha creado la
clase Tobject, de la que deben heredar todas las clases del sistema, o cuando menos,
aquellas que sern susceptibles de ser tratadas en los ficheros. Aunque en principio esto
pueda parecer una restriccin importante, casi todos los sistemas tienen una clase de
referencia de este tipo, con mtodos como ste, que devuelven la longitud de la clase,
y/o mtodos de copia, que devuelven otro objeto exactamente igual al destinatario del
mensaje (de utilidad en el caso de que existan componentes dinmicos dentro del
objeto). Por otra parte, el uso de esta clase padre del resto de las clases puede ocasionar
problemas a la hora de utilizar herencia mltiple; una posible solucin es (al margen de
no utilizar herencia mltiple) limitar este padre tan slo a aquellas clases susceptibles de
que sus instancias sean almacenadas en ficheros, aunque esto, por supuesto no resuelve
el problema en su totalidad. Otra posible solucin es eliminar la clase Tobject, aunque
esto eliminara la posibilidad de calcular la longitud de un objeto que utilice memoria
dinmica.
Por supuesto, siempre es posible sobrecargar los operadores de extraccin para
cada clase y eliminar totalmente el uso de Tobject, pero para sto no es necesario el uso
de las clases aqu presentadas.
El mtodo dev_len(), derivado de Tobject, obligatorio para conocer la longitud
del objeto, puede ser tan sencillo como return sizeof(T) o tan complejo como un
clculo de las longitudes de los componentes dinmicos que contenga el objeto.
Una vez remarcada esta salvedad, estas clases son capaces de leer / escribir
objetos directamente, y gracias a las caractersticas de la programacin orientada a
objetos, estas capacidades pueden sobrecargarse fcilmente para realizar grabaciones
especiales, formatos, o cualquier otro tipo de modificacin respecto a la tpica
write(&a,1,sizeof(.. Se ha desechado en principio la idea de incluir en la clase
Tobject sendos mtodos virtuales de lectura/escritura en fichero, los cules s podran
implicar cambios ms importantes en una estructura de clases ya creada.
Conclusiones.
Ha intentado presentarse en este artculo un conjunto de clases reales que
sustituyen a las clases stream de C++, proporcionando un acceso a ficheros adecuado
al medio, es decir, a un lenguaje de programacin orientado a objetos como es el
C++.
La clase es es la clase base de la que derivan las clases especficas de acceso a ficheros.
No se espera que esta clase sea instanciada.
class es : public Tobject {
protected:
FILE * arch;
char modo[5];
void attach_file(FILE *x) { arch = x; };
void attach_file(char *x) { arch = fopen(x,modo); };
public:
es() { arch = NULL; setmode(esEXIST);};
~es(){ if (arch!=NULL) { fclose(arch); } };
unsigned long read(unsigned char *,unsigned long);
unsigned long write(unsigned char *,unsigned long);
unsigned long moveto(unsigned long);
};
fichero, y tambin la
sfstream()
{};
int write(char x);
int write(int x);
virtual int write(unsigned char *x,unsigned long len);
int write(float x);
virtual int write(Tobject &);
sfstream &operator <<(Tobject &x)
{
this->write(x);
return *this;
};
};
Los mtodos de la clase efstream, que utilizan las llamadas de su case padre, la
es:
int efstream::read(char &x)
{
if (es::read((unsigned char *) &x,sizeof(char))==sizeof(char))
return esTRUE;
else
return esFALSE;
}
int efstream::read(Tobject &x)
{
if (es::read((unsigned char *) &x,x.dev_len())==x.dev_len())
return esTRUE;
else
return esFALSE;
}
else
return esFALSE;
}
Bibliografa.
[1] Garca Perez-Schofield, Jos Baltasar; Prez Cota, Manuel. Problemtica de la E/S
en C++, comparacin con Java. Actas del Congreso Jornadas sobre Objetos98,
Universidad de Deusto, Bilbao. Septiembre 1998.
[2] Garca Perez-Schofield, Jos Baltasar; Prez Cota, Manuel. Implantacin Orientada
a Objetos de un Gestor de Bases de Datos Multiplataforma. Actas del Congreso IV
Jornadas de Informtica, Universidad de Las Lagunas, Las palmas de Gran Canaria.
Julio de 1998.
[3] Borland Intl. Manual de Borland C++, versin 5.00.
[4] GNU. Manual de Gcc versin 2.7.1.
[5] Naughton, Patrick. Manual de Java. Ed. McGraw-Hill, 1996
[6] Stroustrup, Bjarne. A perspective on ISO C++. The C++ Report, Vol. 17/8. Octubre
de 1995. Http:://www.research.att.com/~bs/papers.htm
[7] Gnther Blascheck, Object Oriented Programming with Prototypes. Editorial
Springer-Verlay 1994. ISBN 3-540-56469-1.