DBF File Documentation


Summary

A DBF (Database File) is a single-table database in the dBASE / xBase format: a 32-byte header, an array of column definitions, and fixed-length records. Ashton-Tate’s dBASE introduced it in the early 1980s, and it still carries the attribute table inside every ESRI shapefile. Its MIME type is application/dbf. The usual questions are how to open a .dbf (LibreOffice Calc reads it as a spreadsheet) and how to export it to CSV or XLSX.

Technical details

FeatureValue
Full nameDatabase File (dBASE / xBase table)
File extension.dbf
MIME typeapplication/dbf
Format typeFlat single-table database, fixed-length records (binary)
DeveloperAshton-Tate (dBASE); now a de-facto xBase standard
Introduced1983 (dBASE II/III)
Open standardPartial — widely cloned and documented, no single owner
Byte orderLittle-endian (Intel) for multi-byte header fields
Header length32 bytes, plus 32 bytes per field descriptor
Field terminator0x0D after the last field descriptor
Version flag (byte 0)0x03 dBASE III/IV, 0x83 with .dbt memo, 0x30 Visual FoxPro, 0xF5 FoxPro 2.x
Field typesC (char), N (numeric), D (date), L (logical), M (memo), and later F, I, T, B, Y
Deletion flagFirst byte of each record: space = active, * = deleted
Memo file.dbt (dBASE) / .fpt (FoxPro) — required to read Memo columns
Index files.cdx, .mdx, .ndx, .idx (optional)
Character setDOS/OEM or Windows code page; language-driver byte at header offset 29
Notable useESRI shapefile attribute table (.shp + .dbf)
Related extensions.dbt, .fpt, .cdx, .shp, .csv
Specificationdbase.com/Knowledgebase/INT/db7_file_fmt.htm
File signature (version flag)
03 | 83 | 30 | F5 | ...

Offset 0, 1 byte. A DBF has no fixed magic number; byte 0 is a version flag that also encodes whether a memo file is present. 0x03 is dBASE III/IV with no memo, 0x83 is dBASE III with a .dbt memo, 0x30 is Visual FoxPro, 0xF5 is FoxPro 2.x with a .fpt memo. Bytes 1–3 hold the last-update date as three binary bytes (YY MM DD). Reliable identification uses the version byte together with a valid 32-byte field-descriptor array ending in 0x0D.

What is a DBF file?

DBF stands for database file, the table format of dBASE, the PC database that Ashton-Tate shipped as dBASE II in 1983 and expanded through dBASE III, IV and 5. The format outlived its vendor and became the shared table format of a whole family of compatible products — FoxPro and Visual FoxPro, Clipper, dBASE and dozens of clones — collectively called xBase. Because the layout was simple and well documented, it turned into a de-facto interchange format that is still in daily use four decades later.

A .dbf holds exactly one table. It is not a relational database with multiple linked tables, triggers or SQL inside the file: it is a header describing the columns, followed by rows of fixed-length records. That flat, predictable structure is why it survives. The single largest population of DBF files today is not in accounting or point-of-sale software (though it lives there too) but in geographic information systems: every ESRI shapefile stores its attribute table as a companion .dbf, so anyone who works with map data handles DBFs constantly, often without realising the format is from 1983.

One naming trap is worth clearing up first. The generic label “database file” makes people assume any database is a DBF. It is not. DBF is specifically the dBASE/xBase table format. It is unrelated to SQLite .db files, Microsoft Access .mdb/.accdb, or SQL Server .mdf, even though tools can import a DBF into any of them.

The 32-byte file header

Every DBF opens with a fixed 32-byte header. Unlike most binary formats it has no constant magic number; the very first byte is a version flag that identifies the dialect and signals whether a memo file accompanies the table. Multi-byte integers in the header are little-endian, reflecting the format’s DOS/Intel origins.

offset  size  field
  0      1    version flag (0x03 dBASE III, 0x83 + .dbt memo,
                            0x30 Visual FoxPro, 0xF5 FoxPro 2.x + .fpt)
  1      3    date of last update: YY MM DD (three binary bytes)
  4      4    number of records in the table (uint32, little-endian)
  8      2    number of bytes in the header (uint16)
 10      2    number of bytes in one record (uint16)
 12      2    reserved
 14      1    incomplete-transaction flag
 15      1    encryption flag
 16     12    reserved (multi-user / LAN)
 28      1    MDX flag (0x01 = a production .mdx index exists)
 29      1    language driver / code page byte
 30      2    reserved

Two header fields do most of the work when a reader parses the file. The header length at offset 8 tells the parser exactly where the field descriptors end and the data records begin, so it can jump straight to the first record without counting descriptors. The record length at offset 10 is the stride: because every record is the same size, the byte offset of record n is simply header_length + n × record_length. There is no per-row index and none is needed; random access is pure arithmetic. The record count at offset 4 lets a reader know when to stop, though the file also ends with a 0x1A (Ctrl-Z / EOF) byte in most writers.

The date at offsets 1–3 is a common source of confusion: it is three raw bytes, not ASCII, and the year is stored as an offset from 1900, so a file saved in 2026 records the year byte as 126 (0x7E). The language-driver byte at offset 29 names the code page (for example 0x03 for Windows-1252, 0x65 for DOS/OEM 852), which is the field that decides whether accented text displays correctly.

The field descriptor array

Immediately after the header, starting at byte 32, comes the field descriptor array: one 32-byte block per column. This array is the table’s schema. The array is closed by a single 0x0D (carriage return) terminator byte, which is how a parser knows it has read the last column.

offset  size  field (within each 32-byte descriptor)
  0     11    field name, ASCII, null-padded (max 10 chars + NUL)
 11      1    field type: C N D L M F I T B Y ...
 12      4    field data address (in-memory; ignored on disk)
 16      1    field length in bytes
 17      1    decimal count (for numeric fields)
 18     14    reserved / work-area / MDX flags

The field type at offset 11 is a single ASCII letter, and it determines how the bytes in each record are interpreted. The classic dBASE III types are C character (space-padded text), N numeric (the number stored as ASCII digits, not binary), D date (eight ASCII characters, YYYYMMDD), L logical (one byte: T/F/Y/N/?), and M memo (a pointer into a separate memo file). Later dialects added F float, I integer (a real 4-byte binary integer), T datetime, B double/binary and Y currency.

TypeStored as
CSpace-padded ASCII text, up to 254 bytes
NASCII digits with an optional sign and decimal point, right-justified
DEight ASCII characters, YYYYMMDD
LOne byte: T/F/Y/N, or ? when unset
MTen-digit block number pointing into the .dbt/.fpt memo file

A crucial detail: in a classic DBF, numbers are text. A numeric field of length 8 stores the value 3.14 as the ASCII characters     3.14, right-justified and space-padded, not as an IEEE float. This makes the file human-inspectable in a hex viewer but means numeric precision is limited by the field width the schema declared. The field length at offset 16 is what fixes each column’s byte span, and the sum of all field lengths plus one (for the deletion flag) equals the record length in the header.

The data records and the deletion flag

After the 0x0D terminator, the data records begin. Each record is a flat concatenation of its fields, in schema order, with no delimiters between fields — the reader slices the row using the field lengths from the descriptor array. Every record is prefixed by a single deletion flag byte.

[flag][field 1 bytes][field 2 bytes]...[field N bytes]
 0x20  = active record
 0x2A  = deleted ('*'), still physically present

The deletion flag is a defining quirk of xBase. Deleting a record does not remove it from the file; it only sets the leading byte to * (0x2A). The row still occupies its fixed slot, and the record count is unchanged. Space is reclaimed only by a separate PACK operation that physically rewrites the file. This is why a DBF can look larger than its live row count suggests, and why forensic and recovery tools can often read “deleted” rows straight out of the bytes. An active record carries a space (0x20) in that first byte.

Because records are fixed-width and self-locating, a program can seek to any row instantly, but variable-length content does not fit the model. That is what the memo file solves.

Memo and index companion files

A DBF cannot store long or variable-length text inside the fixed record. When a table needs a Memo (M) column, the record holds only a pointer — a block number — and the actual text lives in a separate memo file that travels alongside the .dbf. In dBASE this file has the extension .dbt; in FoxPro it is .fpt. The memo file is organised in fixed-size blocks (commonly 512 bytes), and the ten-digit number in the DBF record is the block index where that field’s content starts.

The practical consequence matters: if you receive a .dbf that has a Memo column but its .dbt/.fpt is missing, those columns are unrecoverable. The version flag 0x83 (versus plain 0x03) is precisely the signal that a memo file should be present. Keep the set together.

Indexes are the other companion. A DBF has no built-in index; fast lookups come from separate index files — .cdx (compound, FoxPro), .mdx (multiple, dBASE IV) and the older single-key .ndx and .idx. These are optional and rebuildable: a DBF opens and reads fine without them, only sequential scans get slower. The MDX flag at header offset 28 records whether a production .mdx is expected.

DBF inside the ESRI shapefile

The reason DBF is not a historical footnote is geospatial data. An ESRI shapefile is not one file but a set that share a base name: the .shp holds the geometry (points, lines, polygons), the .shx is a geometry index, and the .dbf holds the attribute table — one record per shape, in the same order as the geometry. Feature 1’s attributes are DBF record 1. This one-to-one ordering is the entire link between a map feature and its data.

That coupling is why GIS software (QGIS, ArcGIS) and libraries such as GDAL/OGR read and write DBF constantly. It also inherits DBF’s limits directly into the shapefile spec: field names are capped at 10 characters and column types are the classic dBASE set, which is why shapefile attribute names are so often truncated. When people export a shapefile’s data with ogr2ogr -f CSV out.csv in.dbf, they are reading a 1983 table format straight out of a modern mapping pipeline.

Reading a DBF and getting the data out

A DBF is plain tabular data, so a spreadsheet is the fastest way in. LibreOffice Calc opens a .dbf directly through its dBASE import dialog, where the one setting that matters is the character set: pick the code page that matches the file (the header’s language-driver byte is the hint) or accented text will be garbled. From there, Save As to CSV or XLSX moves the data anywhere. Current Excel imports via Data › Get Data › From File; older Excel opened .dbf natively. For GIS tables, GDAL’s ogr2ogr is the scriptable route and handles the shapefile companions correctly.

Two failure modes cover most “my DBF won’t open” reports. The first is the code-page mismatch above. The second is a missing memo file: if long-text columns come through empty or error out, the .dbt/.fpt was left behind. Neither is a corruption problem, and both are avoidable by keeping the file set intact and choosing the right character set on import.

Frequently asked questions

Why are numbers in a DBF stored as text?

The classic N (numeric) field stores the value as ASCII digits, right-justified and space-padded inside the column’s fixed width, rather than as a binary integer or float. It made early dBASE files portable across machines and readable in a hex editor, at the cost of precision being bounded by the declared field length. Later dialects added true binary types (I integer, B double) for cases where that mattered.

Are deleted DBF records really gone?

No. Deleting a record only sets its leading byte to * (0x2A); the row stays physically in the file at its fixed slot. Only a PACK operation rewrites the file to drop those rows. Until then the data is still present in the bytes, which is why recovery tools can often read it back.

What does the first byte of a DBF tell me?

It is the version flag. 0x03 is dBASE III/IV with no memo, 0x83 is the same with a .dbt memo file, 0x30 marks Visual FoxPro, and 0xF5 marks FoxPro 2.x with an .fpt memo. It identifies both the dialect and whether a companion memo file must be present.

References