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 >> |