A seguir será apresentado o formato do arquivo .DBF, que é o arquivo de banco de dados criado pelo dBASE II. Esse arquivo contém tanto a estrutura de dados da tabela (campos), como os dados da tabela (registros) [1][2].
Tabela 1: Descrição do arquivo .DBF.
| Offset (hexa) |
Tamanho (bytes) |
Descrição |
|---|---|---|
| 0000 | 1 | Versão do dBASE. &H02 = dBASE II. |
| 0001 | 2 | Número de registros no arquivo. |
| 0003 | 1 | Dia da última atualização. |
| 0004 | 1 | Mês da última atualização. |
| 0005 | 1 | Ano da última atualização. |
| 0006 | 2 | Tamanho em bytes de cada registro. |
| 0008 | 32 x 16 | 32 Registros contendo descritores de campos, com 16 bytes cada. Vide tabela 2. |
| 0208 | 1 | Se &H0D, todos os descritores de campo foram utilizados, senão &H00. |
| 0209 | n | Área de dados dos registros. Formato texto. |
Tabela 2: formato do registro de descritores de campo.
| Offset (hexa) |
Tamanho (bytes) |
Descrição |
|---|---|---|
| 0000 | 10 | Nome do campo. Se o primeiro caractere for "&H0D", marca o fim dos descritores. |
| 0010 | 1 | Valor 0. |
| 0011 | 1 | Tipo de dado: 'C' - Caractere 'N' - Numérico 'L' - Lógico |
| 0012 | 1 | Comprimento do campo. |
| 0013 | 2 | Endereço do dado na memória RAM. |
| 0015 | 1 | Número de casas decimais. |
Obs: o offset da tabela 2 é relativo a cada registro, começando pelo endereço &H0008.
A primeira parte do arquivo é um cabeçalho no formato binário, contendo informações gerais do banco de dados.
A segunda parte é também no formato binário e contém informações quanto à estrutura da tabela, ou seja, a descrição de no máximo 32 campos possíveis. As informações de cada campo estão em seqüência.
Por último, a área de dados é toda no formato texto, contendo informação de cada registro em seqüência. O comprimento de cada campo é do tamanho definido na estrutura dos dados. Cada registro é precedido por um byte, onde:
As principais limitações [2] dos arquivos .DBF são apresentadas a seguir.
O programa escrito na linguagem C a seguir, lê um arquivo .DBF e imprime as informações encontradas. Pode ser compilado tanto no PC, como no MSX. No caso do MSX, substituir os sinais de maior menor do "#include" por aspas. Ex: #include "stdio.h".
/*
* Program dbf_print
*
* Author: Marcelo Silveira
* E-mail: flamar98@hotmail.com
* Feb, 2017
*/
#include <stdio.h>
#include <string.h>
struct dbf_header_model
{
unsigned char version;
unsigned int no_records;
unsigned char day, month, year;
unsigned int size_record;
unsigned char no_structures;
} dbf_header;
struct structure_model
{
char name[11];
char data_type;
char length;
char decimal;
int data_addr;
} structure[32];
FILE *fp;
char buffer[1024];
void read_structure()
{
int i;
char p = dbf_header.no_structures;
int offset = 8 + p * 16;
while (buffer[offset] != 0x0D && p<=32)
{
for (i=0; i<11; i++)
structure[p].name[i] = buffer[offset+i];
structure[p].data_type = buffer[offset+11];
structure[p].length = buffer[offset+12];
structure[p].data_addr = buffer[offset+14]*256 + buffer[offset+13];
structure[p].decimal = buffer[offset+15];
offset += 16;
p++;
}
dbf_header.no_structures = p;
}
void read_header()
{
dbf_header.version = buffer[0];
dbf_header.no_records = buffer[2]*256 + buffer[1];
dbf_header.day = buffer[3];
dbf_header.month = buffer[4];
dbf_header.year = buffer[5];
dbf_header.size_record = buffer[7]*256 + buffer[6];
dbf_header.no_structures = 0;
}
void print_data()
{
int i, s, r, count;
int offset = 0x209 + 1;
printf("** Registers **\n");
for (i=0; i<dbf_header.no_records; i++)
{
s=0;
count=0;
for (r=0; r<dbf_header.size_record-1; r++)
{
if (offset+r > 1023)
{
fread(buffer, 1024, 1, fp);
offset=-r;
}
count++;
if (count > structure[s].length)
{
printf(" ");
count=1;
s++;
}
printf("%c", buffer[offset+r]);
}
printf("\n");
offset += dbf_header.size_record;
}
}
void print_structure()
{
int i=0;
printf("** Database structure **\n");
printf("Name, Type, Length, Address in RAM, Decimal\n-------------------------------------------\n");
for (i=0; i<dbf_header.no_structures; i++)
printf("%-11s %c %03d %04X %03d\n", structure[i].name, structure[i].data_type, structure[i].length, structure[i].data_addr, structure[i].decimal);
printf("Total of fields: %d\n\n", dbf_header.no_structures);
}
void print_header()
{
printf("Header of DBF file\n------------------\n");
printf("dBASE version: %d\n", dbf_header.version);
printf("No. Records: %d\n", dbf_header.no_records);
printf("Day: %d\n", dbf_header.day);
printf("Month: %d\n", dbf_header.month);
printf("Year: %d\n", dbf_header.year);
printf("Size of each record: %d\n\n", dbf_header.size_record);
}
void print_DBF()
{
printf("DBF File Reader\n\n");
read_header();
print_header();
read_structure();
print_structure();
print_data();
printf("\nMarMSX 2017\n");
}
void help()
{
printf("** Leitor de arquivos .DBF **\nMarMSX 2017\nUso: dbf_print \nEx: dbf_print myfile.dbf\n");
}
int main(int argc, char* args[])
{
if (argc == 2)
{
if (fp = fopen(args[1],"rb"))
{
fread(buffer, 1024, 1, fp);
print_DBF();
fclose(fp);
}
else
printf("File %s not found!\n", args[1]);
}
else
help();
}
Referências:
[1]- http://www.fileformat.info/format/dbf/corion-dbase-ii.htm
[2] - Cartão de Referência dBASE II. Aventino J.S. Alves. Editora LTC, 1986.
| << Anterior | dBASE II | Próxima >> |