2023年12月22日发(作者:)

.

标准的DBF文件,是由头文件和实体信息两部分构成(如图所示)。

文件头

记录1

记录2

记录3

记录4

……

……

记录n

DBF文件的结构

1)

文件的文件头

其中文件头部分的长度是不定长的,它主要对DBF文件作了一些总体说明(表),其中最主要的是对这个DBF文件的记录项的信息进行了详细地描述,比如对每个记录项的名称、数据类型、长度等信息都有具体的说明。

在文件中的位置

0

1-3

4-7

8-9

10-11

12-13

14

15

16-27

28

内容

1个字节

3个字节

表示当前的版本信息

表示最近的更新日期,按照YYMMDD格式。

说明

1个32位数

文件中的记录条数。

1个16位数

文件头中的字节数。

1个16位数

一条记录中的字节长度。

2个字节

1个字节

1个字节

12个字节

1个字节

保留字节,用于以后添加新的说明性信息时使用,这里用0来填写。

表示未完成的操作。

dBASE IV编密码标记。

保留字节,用于多用户处理时使用。

DBF文件的MDX标识。在创建一个DBF 表时 ,如果使用了MDX 格式的索引文件,那么 DBF 表的表头中的这个字节就自动被设置了一个标志,当你下次试图重新打开这个DBF表的时候,数据引擎会自动识别这个标志,如果此标志为真,则数据引擎将试图打开相应的MDX 文件。

Language driver ID.

保留字节,用于以后添加新的说明性信息时使用,这里用0来填写。

记录项信息描述数组。n表示记录项的个数。这个数组的结构在表2.8中有详细的解释。

作为记录项终止标识。

文件(.dbf)的文件头

29

30-31

32-X

X+1

1个字节

2个字节

(n*32)个字节

1个字节

'.

.

位置

0-10

11

12-15

16

17

20

21-30

31

内容

1个字节

4个字节

1个字节

1个字节

1个字节

说明

记录项的数据类型,是ASCII码值。(B、C、D、G、L、M和N,具体的解释见表2.9)。

记录中该字段的偏移量。

记录项长度,二进制型。

记录项的精度,二进制型。

工作区ID。

11个字节

记录项名称,是ASCII码值。

10个字节

保留字节,用于以后添加新的说明性信息时使用,这里用0来填写。

1个字节

MDX标识。如果存在一个MDX 格式的索引文件,那么这个记录项为真,否则为空。

记录项信息描述

代码

B

C

D

G

N

L

M

Y

F

I

P

数据类型

二进制型 双精度型

字符型

日期型

(Generalor OLE) 通用类型

数值型(Numeric)

逻辑型(Logical)

(Memo)

货币型

浮点型

整形

图片

允许输入的数据

各种字符。

各种字符。

用于区分年、月、日的数字和一个字符,内部存储按照YYYYMMDD格式。

各种字符。

- . 0 1 2 3 4 5 6 7 8 9

? Y y N n T t F f (? 表示没有初始化)。

各种字符。

表2.9 dbf文件中的数据类型

2)

文件的实体信息

实体信息部分就是一条条记录,每条记录都是由若干个记录项构成,因此只要依次循环读取每条记录就可以了。

3)

一个读取dbf文件的例子

假设要读取一个名为soil的dbf文件(存储了土地利用信息),它含有8个记录项,记录项信息如表所示:

记录项名称

Area

数据类型

数值型(double)

长度

31

小数位数

15

'.

.

Perimeter

soils_

soils_id

soil_code

Suit

Centroid_x

Centroid_y

数值型(double)

数值型(int)

数值型(int)

字符型(character)

字符型(character)

数值型(double)

数值型(double)

31

11

11

3

1

31

31

15

0

0

15

15

dbf文件中的数据类型

2、行情文件格式

说明:

(1)、表文件由头记录及数据记录组成。头记录定义该表的结构及与表相关的其他信息。数据记录紧接在头记录之后,包含字段中实际的文本。记录的长度等于所有字段定义的长度之和(以字节为单位)。

(2)、头记录以终止符(0x0D)结束,数据记录以终止符(0x1A)结束。

(3)、表文件中存储整数时低位字节在前。

(4)、数据记录从删除标记字节开始。如果删除标记字节为 ASCII 空格 (0x20),则表示该记录未被删除,如果该字节为星号(0x2A),则表示该记录被删除。在删除标记之后是字段记录中所命名的各字段的数据。

(5)、数据记录都是用ASCII码形式存放的,所以只要读出文件头和字段类型描述区的内容,就可以直接读取dbf文件中的每条记录。

文件头部结构(32字节)

位置

0

1 - 3

4 - 7

8 - 9

10 - 11

12 - 31

长度

1

3

4

2

2

20

含义

文件类型

最近一次更新的时间(YYMMDD)

文件中的记录数目

文件中的第一个数据记录的位置

每个数据记录的长度(包括删除标记)

保留

备注

0x03,FoxBASE+/dBASE III PLUS,无备注

'.

.

32 - n

字段子记录

字段的数目决定了字段子记录的数目。

字段记录结构(32字节)

位置

0 - 10

长度

11

说明

字段名

备注

最多10个字符,若少于10则用空字符填充

11

1

字段类型

C-字符型

Y-货币型

N-数值型

F-浮点型

D-日期型

T-日期时间型

B-双精度型

I-整型

L-逻辑型

M-备注型

G-通用型

C-字符型(二进制)

M-备注型(二进制)

P-图片型

12 - 15

4

记录中该字段的偏移量(16进制)

16

17

18 - 31

n+1 头记录终止符(0x0D),n+2 到 n+264 此范围内的 263 个字节包含后链信息(相关数据库 (.dbc) 的相对路径)。如果第一个字节为 0x00,则该文件不与数据库关联。因此数据库文件本身总是包含 0x00。

数据记录从 除标记字节开始。如果此字节为 ASCII 空格 (0x20),该记录没有删除标记, 如果第一字节为星号 (0x2A),该记录有删除标记。在标记之后是字段记录中所命名各字段中的数据

1

1

14

字段长度

小数位数

保留

以字节为单位

以字节为单位

下面是读取这个dbf文件的代码:

void OnReadDbf(CString Dbf)

'.

.

{

FILE* m_Dbf; //****Dbf文件指针

//打开dbf文件

if((m_Dbf(Dbf,"rb"))==NULL)

{

'.

return;

读取dbf文件的文件头 开始

1, 1,m_Dbf);

fread(date+i, 1, 1,m_Dbf);

//******

sizeof(int), 1,m_Dbf);

sizeof(short), 1,m_Dbf);

sizeof(short), 1,m_Dbf);

} int i,j; //////**** BYTE version; fread(&version,

BYTE date[3]; for(i=0;i<3;i++) {

}

int RecordNum;

fread(&RecordNum,

short HeaderByteNum; fread(&HeaderByteNum,

short RecordByteNum fread(&RecordByteNum,

.

short Reserved1;

fread(&Reserved1, sizeof(short), 1,m_Dbf);

BYTE Flag4s;

fread(&Flag4s, sizeof(BYTE),

1,m_Dbf);

Dbf);

_Dbf);

m_Dbf);

'.

sizeof(BYTE), 1,m_

fread(&Unused, sizeof(int), 1,m

sizeof(BYTE), 1,m_Dbf);

sizeof(BYTE), 1,

sizeof(short), 1,m_Dbf);

BYTE EncrypteFlag; fread(&EncrypteFlag,

for(i=0;i<3;i++) {

} BYTE MDXFlag; fread(&MDXFlag,

BYTE LDriID; fread(&LDriID,

short Reserved2; fread(&Reserved2,

BYTE name[11]; BYTE fieldType;

.

int Reserved3;

BYTE fieldLength;

BYTE decimalCount;

short Reserved4;

BYTE workID;

'.

读取记录项信息-共有8个记录项

//FieldName----11 bytes

fread(name, 11, 1,m_Dbf);

//FieldType----1 bytes

fread(&fieldType, sizeof(BYTE), 1,m_Dbf);

//Reserved3----4 bytes

Reserved3 =0;

fread(&Reserved3, sizeof(int), 1,m_Dbf);

//FieldLength--1 bytes

fread(&fieldLength,sizeof(BYTE), 1,m_Dbf);

//DecimalCount-1 bytes

fread(&decimalCount,sizeof(BYTE), 1,m_Dbf);

//Reserved4----2 bytes

short Reserved5[5]; BYTE mDXFlag1; int fieldscount; fieldscount = (HeaderByteNum - 32) / 32; // for(i=0;i< HeaderByteNum;i++) {

.

Reserved4 =0;

fread(&Reserved4, sizeof(short), 1,m_Dbf);

//WorkID-------1 bytes

fread(&workID, sizeof(BYTE), 1,m_Dbf);

//Reserved5----10 bytes

1,m_Dbf);

1,m_Dbf);

'.

for(j=0;j<5;j++)

{

fread(Reserved5+j,sizeof(short),

}

//MDXFlag1-----1 bytes

fread(&mDXFlag1, sizeof(BYTE),

sizeof(BYTE), 1,m_Dbf);

读取dbf文件头结束

deleteFlag;

读取dbf文件记录 开始

} BYTE terminator; fread(&terminator,

// double Area,Perimeter,Centroid_y,Centroid_x; int Soils_,Soils_id; CString Soil_code,suit; BYTE

char media[31]; // for(i=0;i

.

{

fread(&deleteFlag, sizeof(BYTE), 1,m_Dbf);

//读取 Area double

for(j=0;j<31;j++)

fread(media+j, sizeof(char),

1,m_Dbf);

1,m_Dbf);

1,m_Dbf);

1,m_Dbf);

'.

读取 Perimeter double

fread(media+j, sizeof(char),

读取 soils_ int

strcpy(media+j,"");

fread(media+j, sizeof(char),

=atoi(media);

读取 Soils_id int

strcpy(media+j,"");

fread(media+j, sizeof(char),

Area =atof(media); // for(j=0;j<31;j++)

Perimeter =atof(media); // for(j=0;j<31;j++)

for(j=0;j<11;j++)

Soils_

// for(j=0;j<31;j++)

for(j=0;j<11;j++)

.

Soils_id =atoi(media);

//读取 soil_code string

for(j=0;j<31;j++)

strcpy(media+j,"");

for(j=0;j<3;j++)

1,m_Dbf);

1,m_Dbf);

1,m_Dbf);

'.

fread(media+j, sizeof(char),

=media;

读取 suit string

strcpy(media+j,"");

fread(media+j, sizeof(char),

读取 Centroid_y double

strcpy(media+j,"");

fread(media+j, sizeof(char),

=atof(media);

读取 Centroid_x double

strcpy(media+j,"");

Soil_code

// for(j=0;j<31;j++)

for(j=0;j<1;j++)

suit =media; // for(j=0;j<31;j++)

for(j=0;j<31;j++)

Centroid_y

// for(j=0;j<31;j++)

.

for(j=0;j<31;j++)

fread(media+j, sizeof(char),

1,m_Dbf);

Centroid_x =atof(media);

}

//读取dbf文件记录 结束

}

'.