pcarballosa
Nivel 5
- 1,226
- 1,374
En una época, ahora más o menos remota, los llamados sistemas xBase de gestión de bases de datos (dBase, Foxbase, FoxPro, Clipper, etc.) dominaron la programación de sistemas de bases de datos en las PC, y eso siguió siendo así a lo largo de muchos años.
En realidad los mencionados sistemas no eran la gran cosa, es cierto, o por lo menos en cuanto a las herramientas de desarrollo utilizadas, como se sabe bastante primitivas si las comparamos con algunas de sus contrapartidas más modernas; en eso estamos de acuerdo, sin embargo, a pesar de lo dicho, sin duda alguna los sistemas como dBase fueron capaces de resolver muchos problemas comunes en su era, cuando reinaba el MSDOS en las microcomputadoras del mundo, y no existían muchas más opciones de todos modos.
Nota: El gestor de base de datos dBase II se comenzó a utilizar en la época cuando era común el sistema operativo CP/M de Digital Research en las microcomputadoras de 8 bits, en una época cuando MSDOS no soñaba con nacer todavía.
En todo caso, a pesar de su evidente antigüedad, la forma de guardar los datos utilizada por todos los sistemas mencionados de la familia xBase, o sea, su formato de archivo por lo común con la extensión ".dbf", se sigue usando a menudo, por un lado porque ahora existen sistemas herederos de los originales, y por otro debido a la simplicidad de diseño del mencionado formato interno de los archivos, la cual no sólo hace posible su interpretación por personas sin demasiada experiencia en la programación de computadoras, sino también los convierte en una solución ideal en muchos desarrollos pequeños o limitados.
En particular podemos encontrarnos con archivos propios de los sistemas comentados en muchos Sistemas de Información Geográfica y otros afines.
En cuanto a los sistemas herederos más modernos se pueden citar sistemas gestores de bases de datos mantenidos por empresas o proveedores como XBase++ de Alaska Software y FlagShip; y sería un crimen no mencionar como entre ellos existen también proyectos gratuitos (con licencia GPL) como Harbor y xHarbour, si mal no recuerdo herederos de Clipper; por su parte, en la plataforma .Net de Microsoft se dispone de XSharp, una implementación de un lenguaje xBase para los entornos Visual Studio 2015, 2017 y 2019.
Por todo esto, en este texto vamos a estudiar cómo era (o es) el formato interno de los archivos donde se guardan los datos en los sistemas xBase, como hemos dicho archivos con la extensión ".dbf" en donde está contenida una tabla de datos, puesto en dichos sistemas una base de datos se conforma con una colección de archivos con la mencionada extensión situados en una carpeta.
Por lo demás, en adición a lo comentado también compartiré una implementación de una clase de RapidQ (una implementación de BASIC con cierta limitada orientación a objetos desarrollada por William Yu) por medio de la cual podremos manipular un archivo ".dbf" por nuestra cuenta sin necesidad de otras bibliotecas de terceros; en este caso en particular la clase se hizo pensando en el formato usado en Foxbase, puesto como podremos ver a lo largo de este texto explicativo, entre las muchas versiones y variantes de los sistemas de la familia xBase se presentaron varias diferencias más o menos significativas, casi siempre en cuanto a los tipos de datos soportados.
Nota: La clase para manipular archivos ".dbf" de Foxbase con RapidQ no fue implementada del todo como me hubiera gustado hacerlo, debido en lo fundamental a las características del lenguaje de programación utilizado y a sus limitaciones, pero por lo menos sirve como demostración de la manera de manipular archivos DBF por nuestra cuenta.
En realidad las diferencias entre versiones o productos fueron más grandes cuando se trataba de los archivos índice o los archivos memo, o debido a características propias sólo de un determinado producto, sin embargo, nosotros no trataremos con dichos archivos índice o memo a pesar de ser los índices de uso obligatorio en una base de datos real para poder acelerar las operaciones cuando se buscan datos en las tablas, en especial si estas contienen muchos registros.
En fin, para comenzar consideraré todos conocen el significado de términos básicos propios del mundo de las bases de datos relacionales como podrían ser “registro” o “campo”, dado cada cual podrá preguntar si no es ese el caso.
Por lo general un archivo propio de xBase consiste, como pasa con muchos otros formatos en el mundo de la informática, en una cabecera en donde se guarda información importante a la hora de interpretar el resto de la estructura del archivo; y a continuación de la cabecera se encuentran los datos de la tabla propiamente dichos en un formato ASCII, hasta llegar al final del archivo en donde, opcionalmente, nos podemos encontrar con el código 0x1A para indicárnoslo.
Nota: Los números con un “0x” delante están en un sistema de numeración hexadecimal; éste es el símbolo comúnmente usado en C para denotar los números en dicha base numérica.
La Tabla 1 mostrada a continuación lista los componentes de la cabecera de uno de estos archivos ".dbf" (la parte final de la cabecera puede variar mucho entre versiones):
En la Tabla 1 mostrada anteriormente, los símbolos (FS, D3, D4, D5, Fb, Fp, CL) denotan uno de los productos más específicos de la familia xBase como sigue:
FS = FlagShip D3 = dBase III+
Fb = Foxbase D4 = dBase IV
Fp = FoxPro D5 = dBase V
CL = Clipper
Nota: En donde no se especifica uno de estos símbolos se supone ese valor en particular dentro de la cabecera será interpretado igual con independencia del sistema xBase involucrado.
Por lo demás, en la tabla también podemos observar las inevitables diferencias, no tanto en cuanto a la estructura propiamente dicha como en cuanto a los valores almacenados en las distintas partes de la cabecera de un archivo “.dbf”, producto esto como se comentó de la variedad de entornos de desarrollo donde se los utiliza para almacenar la información, por las respectivas necesidades particulares de cada uno de ellos para poder implementar sus propias características o extensiones.
Por último, en la posición 32 dentro de la cabecera del ".dbf" se encuentra situado un arreglo de descriptores de campo cuyo tamaño, como era de esperarse, está definido por la cantidad de los mismos existentes en una tabla en particular, y por tanto no podemos conocer ese datos antes de toparnos con una tabla real, incluso si se sabe cada uno de dichos descriptores está constituido por 32 bytes de datos.
La estructura de uno de dichos descriptores de campos podemos verla representada en la Tabla 2 mostrada a continuación:
En la Tabla 2 mostrada arriba también nos encontramos con las mismas diferencias debidas a los variados entornos de desarrollo de la familia xBase y a sus necesidades o características propias. En particular, el tipo de campo denotado por uno de los caracteres ASCII “C, D, F, N, L, M, V, P, B, G, 2, 4, 8”, es uno de los valores más afectados por esto, puesto como mencioné en un principio, se pueden encontrar tipos de datos soportados por un entorno y no soportados por otro. En este texto vamos a comentar todos los tipos de datos, no obstante, vamos a implementar nada más los tipos de datos más comunes, para no extendernos demasiado, puesto me sería imposible tratar todas las características.
En la Tabla 3 podemos ver el significado de cada símbolo usado para denotar un tipo de datos de un campo de una base de datos de la familia xBase:
En nuestro caso, de todos los tipos de datos mostrados en la Tabla 3, nada más implementé los correspondientes a los símbolos C, D, N, y L como lo hace Foxbase, puesto son los más comunes y los soportan todos los productos xBase (además de los mencionados Foxbase sólo soporta los campos memo, y como manifesté antes, esos no los trataremos porque no estamos desarrollando un sistema real).
Por último, detrás de la cabecera del archivo “.dbf” comentada hasta este momento, se encuentran situados los registros almacenados dentro de la base de datos o la tabla representada por el mismo, y en este caso cada uno de ellos consiste en una cadena ASCII del largo especificado por la suma de la cantidad de bytes de cada campo existente por separado, más un carácter extra.
Nota: El número para representar la longitud de un registro se guarda en la cabecera del DBF en la posición descrita como el tamaño en bytes del registro.
En particular, la cadena comentada es iniciada con un carácter asterisco (“*”) si ese registro fue eliminado en un momento previo, o con un carácter espacio, si el registro continúa activo.
Nota: En un archivo “.dbf” los registros eliminados en realidad no desaparecen, y por eso pueden ser recuperados con una instrucción Recall propia de dBase, dado sólo se marcan con un asterisco al inicio (código de carácter 0x2A) hasta una llamada a Pack sobre dicho archivo de base de datos, momento cuando todos los registros marcados como eliminados si son removidos de la tabla sin posibilidad de ser recuperados de nuevo.
Es todo, he descrito por completo el formato de un archivo “.dbf” y ahora disponemos de toda la información necesaria para implementar las subrutinas necesarias para poder manipularlo como mismo lo haría un gestor de bases de datos (o casi); como pueden ver, se trata de un formato para una base de datos relacional bastante simple en comparación con otros, como les había comentado en un principio, y por eso no deberemos encontrarnos con grandes problemas; y si a primera vista esto les pareció complicado, no se preocupen, su impresión se debe a haberse descrito todas las características soportadas por los variados entornos, y de este punto en adelante nos será más fácil puesto como he dicho nos centraremos en un archivo propio de Foxbase.
Por supuesto, la información mostrada en este texto fue tomada de distintas fuentes, y por eso en caso de encontrar un error, sería bueno lo comentaran para corregirlo.
Por otro lado, si conocen un sitio web donde se describan más formatos internos de archivos me gustaría pudieran comentarlo; en un época existió uno bastante bueno de nombre wotsit o algo parecido, sin embargo, por lo visto terminó desapareciendo.
Los interesados en ver la implementación práctica de lo comentado pueden hacerlo descargando el código de la clase de RapidQ con el enlace (es necesario Internet): DBFExample.zip.
En este caso dispondrán de una interfaz gráfica para mostrar el contenido de un archivo ".dbf", y también de un par de interfaces de comando destinadas a ver otros datos internos del mismo (los códigos fuente están incluidos).
En todo caso, cada cual puede utilizar el lenguaje de programación de su preferencia en caso de necesitar manipular un archivo DBF por su cuenta, porque para eso sólo necesita la información ofrecida en este texto y un poco de esfuerzo.
En realidad los mencionados sistemas no eran la gran cosa, es cierto, o por lo menos en cuanto a las herramientas de desarrollo utilizadas, como se sabe bastante primitivas si las comparamos con algunas de sus contrapartidas más modernas; en eso estamos de acuerdo, sin embargo, a pesar de lo dicho, sin duda alguna los sistemas como dBase fueron capaces de resolver muchos problemas comunes en su era, cuando reinaba el MSDOS en las microcomputadoras del mundo, y no existían muchas más opciones de todos modos.
Nota: El gestor de base de datos dBase II se comenzó a utilizar en la época cuando era común el sistema operativo CP/M de Digital Research en las microcomputadoras de 8 bits, en una época cuando MSDOS no soñaba con nacer todavía.
En todo caso, a pesar de su evidente antigüedad, la forma de guardar los datos utilizada por todos los sistemas mencionados de la familia xBase, o sea, su formato de archivo por lo común con la extensión ".dbf", se sigue usando a menudo, por un lado porque ahora existen sistemas herederos de los originales, y por otro debido a la simplicidad de diseño del mencionado formato interno de los archivos, la cual no sólo hace posible su interpretación por personas sin demasiada experiencia en la programación de computadoras, sino también los convierte en una solución ideal en muchos desarrollos pequeños o limitados.
En particular podemos encontrarnos con archivos propios de los sistemas comentados en muchos Sistemas de Información Geográfica y otros afines.
En cuanto a los sistemas herederos más modernos se pueden citar sistemas gestores de bases de datos mantenidos por empresas o proveedores como XBase++ de Alaska Software y FlagShip; y sería un crimen no mencionar como entre ellos existen también proyectos gratuitos (con licencia GPL) como Harbor y xHarbour, si mal no recuerdo herederos de Clipper; por su parte, en la plataforma .Net de Microsoft se dispone de XSharp, una implementación de un lenguaje xBase para los entornos Visual Studio 2015, 2017 y 2019.
Por todo esto, en este texto vamos a estudiar cómo era (o es) el formato interno de los archivos donde se guardan los datos en los sistemas xBase, como hemos dicho archivos con la extensión ".dbf" en donde está contenida una tabla de datos, puesto en dichos sistemas una base de datos se conforma con una colección de archivos con la mencionada extensión situados en una carpeta.
Por lo demás, en adición a lo comentado también compartiré una implementación de una clase de RapidQ (una implementación de BASIC con cierta limitada orientación a objetos desarrollada por William Yu) por medio de la cual podremos manipular un archivo ".dbf" por nuestra cuenta sin necesidad de otras bibliotecas de terceros; en este caso en particular la clase se hizo pensando en el formato usado en Foxbase, puesto como podremos ver a lo largo de este texto explicativo, entre las muchas versiones y variantes de los sistemas de la familia xBase se presentaron varias diferencias más o menos significativas, casi siempre en cuanto a los tipos de datos soportados.
Nota: La clase para manipular archivos ".dbf" de Foxbase con RapidQ no fue implementada del todo como me hubiera gustado hacerlo, debido en lo fundamental a las características del lenguaje de programación utilizado y a sus limitaciones, pero por lo menos sirve como demostración de la manera de manipular archivos DBF por nuestra cuenta.
En realidad las diferencias entre versiones o productos fueron más grandes cuando se trataba de los archivos índice o los archivos memo, o debido a características propias sólo de un determinado producto, sin embargo, nosotros no trataremos con dichos archivos índice o memo a pesar de ser los índices de uso obligatorio en una base de datos real para poder acelerar las operaciones cuando se buscan datos en las tablas, en especial si estas contienen muchos registros.
En fin, para comenzar consideraré todos conocen el significado de términos básicos propios del mundo de las bases de datos relacionales como podrían ser “registro” o “campo”, dado cada cual podrá preguntar si no es ese el caso.
Por lo general un archivo propio de xBase consiste, como pasa con muchos otros formatos en el mundo de la informática, en una cabecera en donde se guarda información importante a la hora de interpretar el resto de la estructura del archivo; y a continuación de la cabecera se encuentran los datos de la tabla propiamente dichos en un formato ASCII, hasta llegar al final del archivo en donde, opcionalmente, nos podemos encontrar con el código 0x1A para indicárnoslo.
Nota: Los números con un “0x” delante están en un sistema de numeración hexadecimal; éste es el símbolo comúnmente usado en C para denotar los números en dicha base numérica.
La Tabla 1 mostrada a continuación lista los componentes de la cabecera de uno de estos archivos ".dbf" (la parte final de la cabecera puede variar mucho entre versiones):
Tabla 1: Formato de la cabecera de un archivo “.dbf”
Byte | Tamaño (bytes) | Contenido | Descripción |
00 | 1 | 0x03 | DBF simple (FS, D3, D4, D5, Fb, Fp, CL) |
0x04 | DBF simple (FS, D4, D5) | ||
0x05 | DBF simple (FS, D5, Fp) | ||
0x43 | DBF con memo “.dbv” de tamaño variable (FS) | ||
0xB3 | DBF con memo “.dbv“ y “.dbt” (FS) | ||
0x83 | DBF con memo “.dbt” (FS, D3, D4, D5, Fb, Fp, CL) | ||
0x8B | DBF con memo “.dbt” en formato D4 (D4, D5) | ||
0x8E | DBF con table SQL (D4, D5) | ||
0xF5 | DBF con memo “.fmp” (Fp) | ||
01 | 3 | YYMMDD | Fecha de última actualización |
04 | 4 | Entero largo | Número de registros en el archivo |
08 | 2 | Entero corto | Tamaño en bytes de la cabecera |
10 | 2 | Entero corto | Tamaño en bytes del registro |
12 | 2 | 0x00 | Reservado |
14 | 1 | 0x01 | Transacción iniciada (D4, D5) |
0x00 | Transacción finalizada (D4, D5), ignorado (FS, D3, Fb, Fp, CL) | ||
15 | 1 | 0x01 | Encriptado (D4, D5) |
0x00 | Normal (visible) | ||
16 | 12 | 0x00 | Usado en un entorno multiusuario (D4, D5) |
28 | 1 | 0x01 | Existe índice de producción (Fp, D4, D5) |
0x00 | Índice sobre demanda | ||
29 | 1 | n | Id de manipulador de lenguaje (D4, D5) |
0x01 | Código de página 437 DOS USA (Fp) | ||
0x02 | Código de página 850 DOS Multilenguaje (Fp) | ||
0x03 | Código de página 1251 Windows ANSI (Fp) | ||
0xC8 | Código de página 1250 Windows EE (Fp) | ||
0x00 | Ignorado (FS, D3, Fb, Fp, CL) | ||
30 | 2 | 0x00 | Reservado |
32 | n*32 | --------------- | Descriptor de campo (n indica el número de campos) |
n*32+1 | 1 | 0x0D | Carácter de terminación de cabecera |
En la Tabla 1 mostrada anteriormente, los símbolos (FS, D3, D4, D5, Fb, Fp, CL) denotan uno de los productos más específicos de la familia xBase como sigue:
FS = FlagShip D3 = dBase III+
Fb = Foxbase D4 = dBase IV
Fp = FoxPro D5 = dBase V
CL = Clipper
Nota: En donde no se especifica uno de estos símbolos se supone ese valor en particular dentro de la cabecera será interpretado igual con independencia del sistema xBase involucrado.
Por lo demás, en la tabla también podemos observar las inevitables diferencias, no tanto en cuanto a la estructura propiamente dicha como en cuanto a los valores almacenados en las distintas partes de la cabecera de un archivo “.dbf”, producto esto como se comentó de la variedad de entornos de desarrollo donde se los utiliza para almacenar la información, por las respectivas necesidades particulares de cada uno de ellos para poder implementar sus propias características o extensiones.
Por último, en la posición 32 dentro de la cabecera del ".dbf" se encuentra situado un arreglo de descriptores de campo cuyo tamaño, como era de esperarse, está definido por la cantidad de los mismos existentes en una tabla en particular, y por tanto no podemos conocer ese datos antes de toparnos con una tabla real, incluso si se sabe cada uno de dichos descriptores está constituido por 32 bytes de datos.
La estructura de uno de dichos descriptores de campos podemos verla representada en la Tabla 2 mostrada a continuación:
Tabla 2: Formato del descriptor de campo de un DBF
Byte | Tamaño (bytes) | Contenido | Descripción |
0 | 11 | Caracteres ASCII | Nombre del campo terminado con 0x00 |
11 | 1 | C, D, F, N, L, M, V, P, B, G, 2, 4, 8 | Id de tipo de campo (se explica más adelante) |
12 | 4 | n | Dirección del campo en memoria (D3) |
n | Desplazamiento desde el comienzo del registro (Fp) | ||
0x00 | Ignorado (FS, D4, D5, Fb, CL) | ||
16 | 1 | n | Longitud del campo en bytes |
17 | 1 | n | Posiciones decimales del campo |
18 | 2 | 0x00 | Reservado |
20 | 1 | n | Id de área de trabajo (D4, D5) |
0x00 | No usado (FS, D3, Fb, Fp, CL) | ||
21 | 2 | n | Multiuso dBase (D3, D4, D5) |
0x00 | Ignorado (FS, Fb, Fp, CL) | ||
23 | 1 | 0x01 | Campos conjunto (D3, D4, D5) |
0x00 | Ignorado (FS, Fb, Fp, CL) | ||
24 | 7 | 0x00 | Reservado |
31 | 1 | 0x01 | Campo en índice “.mdx” (D4, D5) |
0x00 | Ignorado (FS, D3, Fb, Fp, CL) |
En la Tabla 2 mostrada arriba también nos encontramos con las mismas diferencias debidas a los variados entornos de desarrollo de la familia xBase y a sus necesidades o características propias. En particular, el tipo de campo denotado por uno de los caracteres ASCII “C, D, F, N, L, M, V, P, B, G, 2, 4, 8”, es uno de los valores más afectados por esto, puesto como mencioné en un principio, se pueden encontrar tipos de datos soportados por un entorno y no soportados por otro. En este texto vamos a comentar todos los tipos de datos, no obstante, vamos a implementar nada más los tipos de datos más comunes, para no extendernos demasiado, puesto me sería imposible tratar todas las características.
En la Tabla 3 podemos ver el significado de cada símbolo usado para denotar un tipo de datos de un campo de una base de datos de la familia xBase:
Tabla 3: La simbología usada para representar los tipos de datos de un campo
Símbolo | Descripción |
C | Cadena (Char): Es una cadena de caracteres ASCII rellenada con espacios hasta alcanzar su longitud declarada. La longitud máxima soportada depende del entorno xBase y es como sigue: n = 1..64 Kb (FS) n = 1..32 Kb (Fp, CL) n = 1..254 (Resto de los sistemas) |
D | Fecha (Date): Es una cadena de caracteres consistente en 8 caracteres ASCII con los dígitos (0..9) representando una fecha en formato YYYYMMDD. |
F | Flotante (Float): Es una cadena de caracteres ASCII con los dígitos (-.0123456789) necesarios para representar un número en punto flotante (FS, D4, D5, Fp). La longitud máxima de la cadena puede ir desde 1 hasta 20. |
N | Numérico (Numeric): Es una cadena de caracteres ASCII con los dígitos (-.0123456789) necesarios para representar un número en punto flotante. En este caso la longitud máxima depende del entorno y puede ser: n = 1..20 (FS, Fp, CL) n = 1..18 (D3, D4, D5, Fb) |
L | Lógico (Logic): Es una cadena de caracteres ASCII de longitud 1 conteniendo uno de los caracteres (YyNnTtFf Space) en FS, D3, Fb, Fp, y CL, o los caracteres (YyNnTtFf ?) en D4 o D5, para representar el contenido de un campo lógico (True o False). |
M | Nota (Memo): Es una cadena de 10 dígitos para representar el número de la posición inicial de los datos reales en el correspondiente archivo “.dbt”; o una cadena vacía de 10 espacios si no existe una entrada en dicho archivo. |
V | Variable: Es una cadena de datos binarios o ASCII guardada en un archivo “.dbv” (FS). En el campo del “.dbf” se guarda lo siguiente: 4 bytes binarios = posición inicial de los datos en archivo “.dbv” 4 bytes binarios = tamaño de datos 1 byte = subtipo 1 byte = reservado (0x1A) En caso de no existir los datos en el archivo “.dbv” el campo almacena 10 espacios en blanco como pasa con los campos memo. |
P | Imagen (Picture): Los datos reales se guardan en formato binario en un archivo “.ftp” (Fp). El campo se trata de forma similar a un memo (n = 10). |
B | Binario (Binary): Los datos reales se guardan en formato binario en un archivo “.dbt” (D5). El campo se trata de forma similar a un memo (n = 10). |
G | General: Es un objeto OLE (D5, Fp). El campo se trata de forma similar a un memo (n = 10). |
2 | Entero corto (Short int): Es un entero corto con signo en binario +/- 32767 (FS). |
4 | Entero largo (Long int): Es un entero largo con signo en binario +/- 2147483647 (FS). |
8 | Doble (Double): Es un número en punto flotante tipo double con signo estándar IEEE (FS). |
En nuestro caso, de todos los tipos de datos mostrados en la Tabla 3, nada más implementé los correspondientes a los símbolos C, D, N, y L como lo hace Foxbase, puesto son los más comunes y los soportan todos los productos xBase (además de los mencionados Foxbase sólo soporta los campos memo, y como manifesté antes, esos no los trataremos porque no estamos desarrollando un sistema real).
Por último, detrás de la cabecera del archivo “.dbf” comentada hasta este momento, se encuentran situados los registros almacenados dentro de la base de datos o la tabla representada por el mismo, y en este caso cada uno de ellos consiste en una cadena ASCII del largo especificado por la suma de la cantidad de bytes de cada campo existente por separado, más un carácter extra.
Nota: El número para representar la longitud de un registro se guarda en la cabecera del DBF en la posición descrita como el tamaño en bytes del registro.
En particular, la cadena comentada es iniciada con un carácter asterisco (“*”) si ese registro fue eliminado en un momento previo, o con un carácter espacio, si el registro continúa activo.
Nota: En un archivo “.dbf” los registros eliminados en realidad no desaparecen, y por eso pueden ser recuperados con una instrucción Recall propia de dBase, dado sólo se marcan con un asterisco al inicio (código de carácter 0x2A) hasta una llamada a Pack sobre dicho archivo de base de datos, momento cuando todos los registros marcados como eliminados si son removidos de la tabla sin posibilidad de ser recuperados de nuevo.
Es todo, he descrito por completo el formato de un archivo “.dbf” y ahora disponemos de toda la información necesaria para implementar las subrutinas necesarias para poder manipularlo como mismo lo haría un gestor de bases de datos (o casi); como pueden ver, se trata de un formato para una base de datos relacional bastante simple en comparación con otros, como les había comentado en un principio, y por eso no deberemos encontrarnos con grandes problemas; y si a primera vista esto les pareció complicado, no se preocupen, su impresión se debe a haberse descrito todas las características soportadas por los variados entornos, y de este punto en adelante nos será más fácil puesto como he dicho nos centraremos en un archivo propio de Foxbase.
Por supuesto, la información mostrada en este texto fue tomada de distintas fuentes, y por eso en caso de encontrar un error, sería bueno lo comentaran para corregirlo.
Por otro lado, si conocen un sitio web donde se describan más formatos internos de archivos me gustaría pudieran comentarlo; en un época existió uno bastante bueno de nombre wotsit o algo parecido, sin embargo, por lo visto terminó desapareciendo.
Los interesados en ver la implementación práctica de lo comentado pueden hacerlo descargando el código de la clase de RapidQ con el enlace (es necesario Internet): DBFExample.zip.
En este caso dispondrán de una interfaz gráfica para mostrar el contenido de un archivo ".dbf", y también de un par de interfaces de comando destinadas a ver otros datos internos del mismo (los códigos fuente están incluidos).
En todo caso, cada cual puede utilizar el lenguaje de programación de su preferencia en caso de necesitar manipular un archivo DBF por su cuenta, porque para eso sólo necesita la información ofrecida en este texto y un poco de esfuerzo.