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文件记录 结束 } '.
发布评论