.dbf file format of dBASE: Java parsing library

Application

dBASE

File extension

dbf

KS implementation details

License: CC0-1.0

This page hosts a formal specification of .dbf file format of dBASE using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Parse a local file and get structure in memory:

Dbf data = Dbf.fromFile("path/to/local/file.dbf");

Or parse structure from a byte array:

byte[] someArray = new byte[] { ... };
Dbf data = new Dbf(new KaitaiStream(someArray));

After that, one can get various attributes from the structure by invoking getter methods like:

data.header1() // => get header1

Java source code to parse .dbf file format of dBASE

Dbf.java

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

import io.kaitai.struct.ByteBufferKaitaiStream;
import io.kaitai.struct.KaitaiStruct;
import io.kaitai.struct.KaitaiStream;
import java.io.IOException;
import java.util.ArrayList;
import java.nio.charset.Charset;

public class Dbf extends KaitaiStruct {
    public static Dbf fromFile(String fileName) throws IOException {
        return new Dbf(new ByteBufferKaitaiStream(fileName));
    }

    public Dbf(KaitaiStream _io) {
        this(_io, null, null);
    }

    public Dbf(KaitaiStream _io, KaitaiStruct _parent) {
        this(_io, _parent, null);
    }

    public Dbf(KaitaiStream _io, KaitaiStruct _parent, Dbf _root) {
        super(_io);
        this._parent = _parent;
        this._root = _root == null ? this : _root;
        _read();
    }
    private void _read() {
        this.header1 = new Header1(this._io, this, _root);
        this._raw_header2 = this._io.readBytes((header1().lenHeader() - 12));
        KaitaiStream _io__raw_header2 = new ByteBufferKaitaiStream(_raw_header2);
        this.header2 = new Header2(_io__raw_header2, this, _root);
        records = new ArrayList<byte[]>((int) (header1().numRecords()));
        for (int i = 0; i < header1().numRecords(); i++) {
            this.records.add(this._io.readBytes(header1().lenRecord()));
        }
    }
    public static class Header2 extends KaitaiStruct {
        public static Header2 fromFile(String fileName) throws IOException {
            return new Header2(new ByteBufferKaitaiStream(fileName));
        }

        public Header2(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Header2(KaitaiStream _io, Dbf _parent) {
            this(_io, _parent, null);
        }

        public Header2(KaitaiStream _io, Dbf _parent, Dbf _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
            _read();
        }
        private void _read() {
            if (_root.header1().dbaseLevel() == 3) {
                this.headerDbase3 = new HeaderDbase3(this._io, this, _root);
            }
            if (_root.header1().dbaseLevel() == 7) {
                this.headerDbase7 = new HeaderDbase7(this._io, this, _root);
            }
            fields = new ArrayList<Field>((int) (11));
            for (int i = 0; i < 11; i++) {
                this.fields.add(new Field(this._io, this, _root));
            }
        }
        private HeaderDbase3 headerDbase3;
        private HeaderDbase7 headerDbase7;
        private ArrayList<Field> fields;
        private Dbf _root;
        private Dbf _parent;
        public HeaderDbase3 headerDbase3() { return headerDbase3; }
        public HeaderDbase7 headerDbase7() { return headerDbase7; }
        public ArrayList<Field> fields() { return fields; }
        public Dbf _root() { return _root; }
        public Dbf _parent() { return _parent; }
    }
    public static class Field extends KaitaiStruct {
        public static Field fromFile(String fileName) throws IOException {
            return new Field(new ByteBufferKaitaiStream(fileName));
        }

        public Field(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Field(KaitaiStream _io, Dbf.Header2 _parent) {
            this(_io, _parent, null);
        }

        public Field(KaitaiStream _io, Dbf.Header2 _parent, Dbf _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
            _read();
        }
        private void _read() {
            this.name = new String(this._io.readBytes(11), Charset.forName("ASCII"));
            this.datatype = this._io.readU1();
            this.dataAddress = this._io.readU4le();
            this.length = this._io.readU1();
            this.decimalCount = this._io.readU1();
            this.reserved1 = this._io.readBytes(2);
            this.workAreaId = this._io.readU1();
            this.reserved2 = this._io.readBytes(2);
            this.setFieldsFlag = this._io.readU1();
            this.reserved3 = this._io.readBytes(8);
        }
        private String name;
        private int datatype;
        private long dataAddress;
        private int length;
        private int decimalCount;
        private byte[] reserved1;
        private int workAreaId;
        private byte[] reserved2;
        private int setFieldsFlag;
        private byte[] reserved3;
        private Dbf _root;
        private Dbf.Header2 _parent;
        public String name() { return name; }
        public int datatype() { return datatype; }
        public long dataAddress() { return dataAddress; }
        public int length() { return length; }
        public int decimalCount() { return decimalCount; }
        public byte[] reserved1() { return reserved1; }
        public int workAreaId() { return workAreaId; }
        public byte[] reserved2() { return reserved2; }
        public int setFieldsFlag() { return setFieldsFlag; }
        public byte[] reserved3() { return reserved3; }
        public Dbf _root() { return _root; }
        public Dbf.Header2 _parent() { return _parent; }
    }

    /**
     * @see <a href="http://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm">- section 1.1</a>
     */
    public static class Header1 extends KaitaiStruct {
        public static Header1 fromFile(String fileName) throws IOException {
            return new Header1(new ByteBufferKaitaiStream(fileName));
        }

        public Header1(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Header1(KaitaiStream _io, Dbf _parent) {
            this(_io, _parent, null);
        }

        public Header1(KaitaiStream _io, Dbf _parent, Dbf _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
            _read();
        }
        private void _read() {
            this.version = this._io.readU1();
            this.lastUpdateY = this._io.readU1();
            this.lastUpdateM = this._io.readU1();
            this.lastUpdateD = this._io.readU1();
            this.numRecords = this._io.readU4le();
            this.lenHeader = this._io.readU2le();
            this.lenRecord = this._io.readU2le();
        }
        private Integer dbaseLevel;
        public Integer dbaseLevel() {
            if (this.dbaseLevel != null)
                return this.dbaseLevel;
            int _tmp = (int) ((version() & 7));
            this.dbaseLevel = _tmp;
            return this.dbaseLevel;
        }
        private int version;
        private int lastUpdateY;
        private int lastUpdateM;
        private int lastUpdateD;
        private long numRecords;
        private int lenHeader;
        private int lenRecord;
        private Dbf _root;
        private Dbf _parent;
        public int version() { return version; }
        public int lastUpdateY() { return lastUpdateY; }
        public int lastUpdateM() { return lastUpdateM; }
        public int lastUpdateD() { return lastUpdateD; }
        public long numRecords() { return numRecords; }
        public int lenHeader() { return lenHeader; }
        public int lenRecord() { return lenRecord; }
        public Dbf _root() { return _root; }
        public Dbf _parent() { return _parent; }
    }
    public static class HeaderDbase3 extends KaitaiStruct {
        public static HeaderDbase3 fromFile(String fileName) throws IOException {
            return new HeaderDbase3(new ByteBufferKaitaiStream(fileName));
        }

        public HeaderDbase3(KaitaiStream _io) {
            this(_io, null, null);
        }

        public HeaderDbase3(KaitaiStream _io, Dbf.Header2 _parent) {
            this(_io, _parent, null);
        }

        public HeaderDbase3(KaitaiStream _io, Dbf.Header2 _parent, Dbf _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
            _read();
        }
        private void _read() {
            this.reserved1 = this._io.readBytes(3);
            this.reserved2 = this._io.readBytes(13);
            this.reserved3 = this._io.readBytes(4);
        }
        private byte[] reserved1;
        private byte[] reserved2;
        private byte[] reserved3;
        private Dbf _root;
        private Dbf.Header2 _parent;
        public byte[] reserved1() { return reserved1; }
        public byte[] reserved2() { return reserved2; }
        public byte[] reserved3() { return reserved3; }
        public Dbf _root() { return _root; }
        public Dbf.Header2 _parent() { return _parent; }
    }
    public static class HeaderDbase7 extends KaitaiStruct {
        public static HeaderDbase7 fromFile(String fileName) throws IOException {
            return new HeaderDbase7(new ByteBufferKaitaiStream(fileName));
        }

        public HeaderDbase7(KaitaiStream _io) {
            this(_io, null, null);
        }

        public HeaderDbase7(KaitaiStream _io, Dbf.Header2 _parent) {
            this(_io, _parent, null);
        }

        public HeaderDbase7(KaitaiStream _io, Dbf.Header2 _parent, Dbf _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
            _read();
        }
        private void _read() {
            this.reserved1 = this._io.ensureFixedContents(new byte[] { 0, 0 });
            this.hasIncompleteTransaction = this._io.readU1();
            this.dbaseIvEncryption = this._io.readU1();
            this.reserved2 = this._io.readBytes(12);
            this.productionMdx = this._io.readU1();
            this.languageDriverId = this._io.readU1();
            this.reserved3 = this._io.ensureFixedContents(new byte[] { 0, 0 });
            this.languageDriverName = this._io.readBytes(32);
            this.reserved4 = this._io.readBytes(4);
        }
        private byte[] reserved1;
        private int hasIncompleteTransaction;
        private int dbaseIvEncryption;
        private byte[] reserved2;
        private int productionMdx;
        private int languageDriverId;
        private byte[] reserved3;
        private byte[] languageDriverName;
        private byte[] reserved4;
        private Dbf _root;
        private Dbf.Header2 _parent;
        public byte[] reserved1() { return reserved1; }
        public int hasIncompleteTransaction() { return hasIncompleteTransaction; }
        public int dbaseIvEncryption() { return dbaseIvEncryption; }
        public byte[] reserved2() { return reserved2; }
        public int productionMdx() { return productionMdx; }
        public int languageDriverId() { return languageDriverId; }
        public byte[] reserved3() { return reserved3; }
        public byte[] languageDriverName() { return languageDriverName; }
        public byte[] reserved4() { return reserved4; }
        public Dbf _root() { return _root; }
        public Dbf.Header2 _parent() { return _parent; }
    }
    private Header1 header1;
    private Header2 header2;
    private ArrayList<byte[]> records;
    private Dbf _root;
    private KaitaiStruct _parent;
    private byte[] _raw_header2;
    public Header1 header1() { return header1; }
    public Header2 header2() { return header2; }
    public ArrayList<byte[]> records() { return records; }
    public Dbf _root() { return _root; }
    public KaitaiStruct _parent() { return _parent; }
    public byte[] _raw_header2() { return _raw_header2; }
}