You found a file called CUSTOMER.DBF on an old drive, or exported one from a GIS tool, an
inventory system, or some other application built decades ago — and unlike every other legacy
format on this site, opening it in a text editor gets you nothing but garbage characters. That's
because DBF, unlike BAI2, NACHA, IIF, or CSV, is binary. This article explains what's
actually inside one.
What a DBF file is
DBF is the table storage format behind dBase, one of the first mass-market database
programs, and its many descendants — FoxPro, Visual FoxPro, Clipper, and countless business
applications built on top of them. A .dbf file is a database table: it defines a schema (a
fixed list of named, typed columns) and stores one binary record per row, all in a single file.
No SQL, no server — just a self-contained file a program reads directly.
That directness is exactly why it stuck around in point-of-sale systems, inventory management, and line-of-business software for decades, and why GIS tools like shapefiles still use DBF today for attribute tables (the non-geometry data attached to map features).
The structure: header, fields, records
A DBF file has three parts, read in order:
- A 32-byte header with the record count, where the field descriptors end, how many bytes each record takes, a "last updated" date, and a code page byte that says how to decode text.
- A field descriptor table — one 32-byte entry per column, each holding the field's name (up
to 11 characters), its type, and its width. This table ends with a single
0x0Dmarker byte. - The records themselves — one fixed-width binary block per row, back to back, with no separators. Every record starts with a 1-byte deletion flag, then each field's value packed to its declared width in the exact order the field descriptors listed them.
Because widths are fixed and declared up front, a DBF reader doesn't need to scan for delimiters
at all — it just seeks straight to header_size + (record_number × record_length) to jump to any
record directly. That's fast, but it also means the file is meaningless without correctly reading
the schema first.
Field types you'll see
- C (Character) — text, space-padded to the field's declared width.
- N / F (Numeric / Float) — digits stored as plain ASCII text (not raw binary numbers), right-aligned within the field width, with a declared decimal place count.
- D (Date) — always exactly 8 digits,
YYYYMMDD, no separators. - L (Logical) — a single character:
T/F(orY/N), with a blank or?meaning unknown. - M (Memo) — not the text itself, but a pointer into a separate companion file (
.dbtin dBase III/IV,.fptin FoxPro) that holds variable-length text too long to fit in a fixed-width field. Without that second file, a memo field's actual content isn't recoverable from the.dbfalone. - I (Integer) — a FoxPro extension: unlike N/F, this one really is raw 4-byte binary, not ASCII digits.
The deletion quirk
Deleting a record in a dBase/FoxPro tool doesn't remove it from the file — it just flips that
record's leading byte from a space to an asterisk (*). The record stays in place, full size,
until someone runs a "pack" operation to actually compact the table and reclaim the space. A
casual byte-count of a DBF file can therefore overstate how much live data it holds; a proper
reader has to check that flag on every record.
Reading a DBF file today
Renaming .dbf to anything else won't help — Excel and text editors have no idea how to decode
a binary header or a code-page-dependent character encoding. The free
DBF to CSV converter here on LegacyFile reads the whole structure directly
in your browser: it parses the header and field descriptors, decodes every record (including
deleted ones, which it flags rather than hides), and flattens the table into one row per record
you can export as CSV, XLSX, or JSON. See
How to open a DBF file without dBase or FoxPro for the
step-by-step version.