Версия для печати


Структура DBF-файлов для непродвинутых
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=624

Александр Терехов
дата публикации 17-07-2002 15:30

Структура DBF-файлов для непродвинутых

Вступление

Все было бы хорошо, если бы не BDE...
Нет, BDE - это очень даже хорошо, плохо то, что использовав в программе однажды TTable, приходится ломать голову над тем, как же с минимальными потерями "прикрутить" BorlandDatabaseEngine к пользовательской машине. Это первое, что заставляет сесть за изучение заголовков DBF-файлов. И второе. Эти самые DBF-файлы имеют такую особенность, как разрушение заголовков. И третье, и четвертое, и пятое...

Для Вас не составляет сложности написать компонент, который работает с DBF-таблицами?.

В этом случае НЕМЕДЛЕННО прекратите чтение статьи!

А мы же посмотрим, что из себя представляют заголовки DBF-файлов и как можно использовать свои знания о них в практическом применении.

Структура DBF-файла

DBF-файл состоит из двух частей: Схематично все это можно представить так:
Таблица 1. Структура DBF-файла
Кол-во байтНаименование
32 Заголовок DBF-файла
32 Описание первого поля
32 Описание второго поля
... ...
32 Описание n-го поля
1 Завершающий символ 0x0D (13)
RecordSize Первая запись из n-полей
RecordSize Вторая запись из n-полей
... ...
RecordSize m-я запись из n-полей, где m=RecordsCount
1 Завершающий символ 0x1A (26)

RecordSize (размер записи в байтах) и RecordsCount (количество записей), значения которых берутся из заголовка DBF-файла, будут рассмотрены ниже.
Теперь, когда мы знаем из каких частей состоит DBF-файл и какой размер они имеют, перейдем к более подробному рассмотрению их структуры.

Описание заголовка DBF-файла

Как видно из предыдущей таблицы, заголовок состоит из трех частей: Размер "собственно заголовка" составляет 32 байта, каждый из которых несет строго определенное значение.

Таблица 2. Структура DBF-заголовка
№ байта Размер Значение Описание Используется
00 1 0x03(3) простая таблица FS, D3, D4, D5, Fb, Fp, CL
0x04(4) простая таблица D4, D5 (FS)
0x05(5) простая таблица D5, Fp (FS)
0x43(67) с мемо-полем .dbv FS
0xB3(179) с мемо-полями .dbv .dbt FS
0x83(131) с мемо-полем .dbt FS, D3, D4, D5, Fb, Fp, CL
0x8B(139) с мемо-полем .dbt формат D4 D4, D5
0x8E(142) SQL-таблица D4, D5
0xF5(245) с мемо полем .fmp Fp
01 1 YY Год последнего обновления таблицы Все
02 1 MM Месяц последнего обновления таблицы Все
03 1 DD День последнего обновления таблицы Все
04 4 RecordsCount Количество записей в таблице Все
08 2 HeaderSize Размер заголовка в байтах Все
10 2 RecordSize Размер записи в байтах Все
12 2 0x00,0x00 Зарезервировано Все
14 1 0x01 Начало транзакции D4, D5
0x00 Конец транзакции D4, D5
0x00 Игнорируется FS, D3, Fb, Fp, CL
15 1 0x01 Закодировано D4, D5
0x00 Нормальная видимость Все
16 12 0 (1) Использование многопользовательского окружения D4, D5
28 1 0x01 Используется индекс Fp, D4, D5
0x00 Индекс не используется Все
29 1 n Номер драйвера языка D4, D5
0x01(1) кодовая страница 437 DOS USA Fp
0x02(2) кодовая страница 850 DOS Multilang Fp
0x26(38) кодовая страница 866 DOS Russian Fp
0x57(87) кодовая страница 1251 Windows ANSI Fp
0xC8(200) кодовая страница 1250 Windows EE Fp
0x00(0) игнорируется FS, D3, Fb, Fp, CL
30 2 0x00,0x00 Зарезервировано Все

Таким образом мы сумели описать первых 32 байта DBF-файла. Начиная с 33 байта начинаются описания полей, каждое из которых также имеет размер в 32 байта.

Структура описания полей в заголовке DBF-файла

Таблица 3. Структура описания полей в заголовке DBF-файла
№ байта Размер Значение Описание Используется
00 11 ASCII Имя поля с 0x00 завершением Все
11 1 ASCII Тип поля см. Таблицу 4 Все
12 4 n,n,n,n Адрес поля в памяти D3
0,0,n,n Смещение относительно начала записи Fp
0,0,0,0 Игнорируется FS, D4, D5, Fb, CL
16 1 Byte Размер поля см. Таблицу 4 Все
17 1 Byte Количество знаков после запятой Все
18 2 0,0 Зарезервировано Все
20 1 Byte Идентификатор рабочей области D4,D5
0x00 Не используется FS, D3, Fb, Fp, CL
21 2 n,n Многопользовательский dBase D3, D4, D5
0,0 Игнорируется FS Fb, Fp, CL
23 1 0x01 Установленные поля D3, D4, D5
0x00 Игнорируется FS Fb, Fp, CL
24 7 0..0 Зарезервировано Все
31 1 0x01 Поле включено в .mdx индекс D4, D5
0x00 Игнорируется D3, FS, Fb, Fp, CL

Таблица 4. Типы полей и их размеры
Код Тип Размер Описание/Размер Используется
C 1..n Char n ASCII символов Все
пустые места - пробел 0x20(32)
n = 1..64Kbt FS
n = 1..32Kbt Fp, CL
n = 1..254 Все
D 8 Date 8 ASCII знаков (0..9) в формате YYYYMMDD Все
F 1..n Float ASCII символы(-.0123456789)
переменная позиция плавающей точки
n = 1..20
FS, D4, D5, Fp
N 1..n Numeric ASCII символы (-.0123456789)
фиксированная позиция точки
Все
n = 1..20 FS, Fp, CL
n = 1..18 D3, D4, D5, Fb
L 1 Logical ASCII символы (Yy Tt Nn Ff, пробел - не определено) FS, D3, Fb, Fp, CL
ASCII символы (Yy Tt Nn Ff, ? - не определено) D4, D5 (FS)
M 10 Memo 10 цифр, определяющих начало блока данных в .dbt-файле
или 10 пробелов, если поле мемо пусто
Все
V 10 Variable Переменная Bin/ASCII данных в .dbv-файле
4 Bin байтов - начало блока в мемо-файле
4 Bin байтов - размер блока
1 Bin байт - подтип данных
1 Bin байт - зарезервировано 0x1A(26)
FS
P 10 Picture Binary данные в .ftp-файле
структура такая же как и в Memo-типе
Fp
B 10 Binary Binary данные в .dpt-файле
структура такая же как и в Memo-типе
D5
G 10 General OLE-объекты
структура такая же как и в Memo-типе
D5, Fp
2 2 short int Binary int max +/- 32767 FS
4 4 long int Binary int max +/- 2147483647 FS
8 8 double Binary signed double IEEE FS

Завершает описание заголовка символ 0x0D(13)

Теперь уже можно сделать кое-какие вычисления. Например, определить количество полей в DBF-файле.
Размер заголовка DBF-файла в байтах составляет:
32+32xN+1 байт, где N - количество полей.
Этот же размер можно извлечь из 8,9 байтов заголовка - HeaderSize
Следовательно количество полей равно:
N:=(HeaderSize-33)/32 байт.
Сместившись на HeaderSize байт от начала файла, мы переходим к непосредственно к самим записям, размер которых указан в 10,11 байтах заголовка - RecordSize, а их количество в 04..07 байтах - RecordsCount.
Структура записи в DBF-файле более простая.

Структура записи в DBF-файле

Каждая запись имеет следующую структуру.
Таблица 5. Структура записи в DBF-файле
№ байта Размер Описание Используется
0 1 Флаг удаления "*", иначе - пробел Все
1 1..n Различные типы полей фиксированной длины
без завершающих символов
длина поля n определяется в 16 байте структуры описания поля.
Все

Завершает DBF-файл символ 0x1A(26)

Таким образом, в общем случае запись - это строка символов (кроме FS), состоящая из частей (полей) строго определенного размера. Эти размеры указаны в структуре описания поля в 16-м байте.

ВЫВОДЫ

Теперь, изучив строение структуры DBF-файла мы можем:
  1. Получить важные сведения о DBF-файле из его первых 32 байтов
  2. Изменить несколько важных значений DBF-файла:
    • изменить языковой драйвер таблицы
    • отвязать таблицу от индексного файла
    • по желанию - еще что-нибудь
  3. Определить количество и тип полей в DBF-файле
  4. Отследить разрушение заголовка DBF-файла путем расчета места нахождения завершающего заголовок символа и сравнения его с 0x0D(13)
  5. Попытаться восстановить заголовок
  6. Создать примитивный драйвер работы с DBF-файлом без BDE
  7. И многое, многое другое...

Небольшой пример

Пример примитивного драйвера работы с DBF-файлом без BDE и возможности изменения заголовка DBF-файла находится в файле DBHeader.zip (7K)
Пример подробно откомментирован, поэтому в тексте статьи приводить его не буду. Тем более что, как говорится, "лучше один раз увидеть"...
В качестве полигона можно использовать DBF-таблицы, поставляемые вместе с Delphi: \DelphiX\Demos\Data\*.dbf

В дополнение к материалу: DBFCodePage.zip (1.7K) небольшой перекодировщик (языковой драйвер) ascii ANSI Win 1251 в dBase RUS cp866 и обратно.

©  Терехов Александр