A dBase File has a prefix, a header and rows of data.
Prefix - id (byte) - year (byte) - month (byte) - day (byte) - Number of records (UInt32) - headersite (Uint16) - RecordSize (Uint16) - 20 fillbytes
Byte/Offset
Number of Bytes
Description
0
1
dBase Version, Valid dBASE for Windows table file, bits 0-2 indicate version number: 3 for dBASE Level 5, 4 for dBASE Level 7.
Bit 3 and bit 7 indicate presence of a dBASE IV or dBASE for Windows memo file; bits 4-6 indicate the presence of a dBASE IV SQL table; bit 7 indicates the presence of any .DBT memo file (either a dBASE III PLUS type or a dBASE IV or dBASE for Windows memo file).
1-3
3
YY / MM / DD
4-7
unsgined 32 Bit
Number of records
8-9
unsgined 16 Bit
Number of bytes in the header
10-11
unsgined 16 Bit
Number of bytes in the records
12-13
2
reserved
14
1
Flag indicating incomplete dBASE IV transaction.
15
1
dBASE IV encryption flag.
16-27
12
reserved
28
1
Production MDX flag; 0x01 if a production .MDX file exists for this table; 0x00 if no .MDX file exists.
29
1
Language driver ID
30-31
2
Reserved
32-63
32
Language driver name
64-67
4
Reserved
68-n
48 Byte each
Field descriptor
n+1
1
Field descriptor terminator
n+2
Field descriptor
Byte/Offset
Number of Bytes
Description
0-31
32
Fieldname (zero-filled) read only until byte-value are zero
32
1
Field type in ASCII (B, C, D, N, L, M, @, I, +, F, 0 or G). B: blog C: Chars D: Date N: Numeric L: Logical, boolean I: Integer
35-36
2
reserved
37
1
Production .MDX field flag; 0x01 if field has an index tag in the production .MDX file; 0x00 if the field is not indexed.
38-39
2
reserved
40-43
4
Next Autoincrement value, if the Field type is Autoincrement, 0x00 otherwise.
44-47
4
reserved
Source classes (C#)
class Dbheader3 {
public byte id; // 2=dbase2 3=dbase3 131=dBase3 mit Memofeld
public byte jahr; // datum
public byte monat;
public byte tag;
public UInt32 anzrec; // Anzahl der Datensaetze */
public UInt16 headersize; // Headergroesse in Byte */
public UInt16 recsize; // Laenge eines einzelnen Datensatzes
public byte[] dummy;
}
class Field {
public String fieldname; // 11 Zeichen
public char typ; // C=String; N=Zahl; D=Datum; L=Boolean M=Memotext
public UInt32 fieldadr; // Anzahl der Datensaetze */
public byte size;
public byte nk;
// 14 dummys
public UInt16 offset;
}
class Row {
private static byte[] dummy = new byte[255];
public List
Source methods of the classes (C#)
class Dbheader3 {
public byte id; // 2=dbase2 3=dbase3 131=dBase3 mit Memofeld
public byte jahr; // datum
public byte monat;
public byte tag;
public UInt32 anzrec; // Anzahl der Datensaetze */
public UInt16 headersize; // Headergroesse in Byte */
public UInt16 recsize; // Laenge eines einzelnen Datensatzes
public byte[] dummy;
}
class Field {
public String fieldname; // 11 Zeichen
public char typ; // C=String; N=Zahl; D=Datum; L=Boolean M=Memotext
public UInt32 fieldadr; // Anzahl der Datensaetze */
public byte size;
public byte nk;
// 14 dummys
public UInt16 offset;
}
class Row {
public void loadRow(BinaryReader inStream, List fieldlist) {
String strValue;
Decimal decValue;
int intValue;
foreach (Field_rec fieldrec in fieldlist) {
switch (fieldrec.typ) {
case 'C': // read size bytes
dummy = inStream.ReadBytes(fieldrec.size);
sb.Clear();
for (int i = 0; i < fieldrec.size; i++) {
sb.Append(((char)dummy[i]).ToString());
}
strValue = sb.ToString();
attribs.Add(strValue.Trim().Clone());
break;
case 'I': // read size bytes Integer
dummy = inStream.ReadBytes(fieldrec.size);
sb.Clear();
for (int i = 0; i < fieldrec.size; i++) {
sb.Append(((char)dummy[i]).ToString());
}
strValue = sb.ToString();
if (int.TryParse(strValue, out intValue))
attribs.Add(intValue);
else
attribs.Add(0);
break;
case 'F':
// n nk 10/4 12345.1234
dummy = inStream.ReadBytes(fieldrec.size);
sb.Clear();
for (int i = 0; i < fieldrec.size; i++) {
sb.Append(((char)dummy[i]).ToString());
}
strValue = sb.ToString().Trim();
if (Decimal.TryParse(strValue,
System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowLeadingSign,
System.Globalization.CultureInfo.InvariantCulture, out decValue))
attribs.Add(decValue);
else
attribs.Add(0.0);
break;
case 'L':
dummy = inStream.ReadBytes(fieldrec.size);
if (dummy.Equals("T") || dummy.Equals("True") || dummy.Equals("Wahr"))
attribs.Add(true);
else
attribs.Add(true);
break;
case 'D':
dummy = inStream.ReadBytes(fieldrec.size);
sb.Clear();
for (int i = 0; i < fieldrec.size; i++) {
sb.Append(((char)dummy[i]).ToString());
}
strValue = sb.ToString();
attribs.Add(strValue.Clone());
break;
case 'M':
break;
} // switch
}
}
}
Start the programm
public String readdBaseFile2String(String filename) {
const byte eof = 26;
const byte rowIsDelete = 42; // *
StringBuilder sb = new StringBuilder();
List tabelle = new List();
FileStream inFile = null;
BinaryReader inStream = null;
try {
Dbheader3 header = new Dbheader3();
inFile = new FileStream(filename, FileMode.Open);
inStream = new BinaryReader(inFile);
header.load1(inStream);
sb.AppendLine("Header: ");
sb.AppendLine(header.ToString());
// Felder bestimmen
List fieldlist = new List();
Field_rec field;
while (true) {
field = new Field_rec();
field.load(inStream);
String name = field.fieldname;
fieldlist.Add(field);
long position = inFile.Position;
// Preview für
byte eoffield = inStream.ReadByte();
if (eoffield == 13) {
break;
}
else {
inFile.Seek(position, SeekOrigin.Begin);
}
}
sb.AppendLine();
sb.AppendLine("Felder");
foreach (Field_rec fieldloop in fieldlist) {
sb.AppendLine(fieldloop.ToString());
}
byte flag;
Row row;
// vor jedem Datensatz steht das "Deleteflag 20=okay 46=gelöscht
while (true) {
flag = inStream.ReadByte(); // space oder * oder 1A
if (flag == eof) {
break;
} // if (flag!=eof) {
row = new Row();
row.loadRow(inStream, fieldlist);
if (flag != rowIsDelete) {
tabelle.Add(row);
}
//
} // while
int anzDatensaetze = tabelle.Count;
sb.AppendLine("anzDatensaetze:" + anzDatensaetze);
foreach (Row rowloop in tabelle) {
rowloop.printFields(sb);
}
inStream.Close();
inFile.Close();
}
catch (Exception e) {
sb.AppendLine("Fehler beim Öffnen der Datei:");
sb.Append(" ");
sb.AppendLine(filename);
sb.AppendLine("Fehlermeldung:");
sb.Append(" ");
sb.AppendLine(e.ToString());
inStream.Close();
inFile.Close();
}
return sb.ToString();
}