下载此文档

DBF文件格式详细说明及程序设计.pdf


文档分类:IT计算机 | 页数:约15页 举报非法文档有奖
1/15
下载提示
  • 1.该资料是网友上传的,本站提供全文预览,预览什么样,下载就什么样。
  • 2.下载该文档所得收入归上传者、原创者。
  • 3.下载的文档,不会出现我们的网址水印。
1/15 下载此文档
文档列表 文档介绍
该【DBF文件格式详细说明及程序设计 】是由【小s】上传分享,文档一共【15】页,该文档可以免费在线阅读,需要了解更多关于【DBF文件格式详细说明及程序设计 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。:.
DBF文件格式详细说明及程序设计
三峡大学水利与环境学院肖泽云
1DBF文件格式说明
DBF文件是一种以二进制进行存储的表格数据文件,其文件内部有着严格的
格式要求,具体由文件头和记录项组成。其中文件头中包括字段的相关信息。DBF
文件的数据结构如下表所示:
组成内容位置(Byte)说明
文件头文件头定义0-31包括版本信息、更
新时间、记录条
数、文件头长度等
字段1定义32-64字段名称、类型、
字段长度(Byte)、
精度等
字段2定义65-97同上
……同上
字段n定义-n*32+31同上
值为0x0Dn*32+32表示终止字段定

表格记录数据第1行数据n*32+33-X表示第1行数据
第2行数据表示第2行数据
……
注意,在表格记录数据中每行数据具体占多长字节,这个由文件头中定义
的字段数目以及字段长度来决定,如果该文件一共只有两个字段,其中第一个字
段为数值,其长度为4,第二个字段为字符串,长度为50,则每一行数据占的字
节长度为4+50=54,在读取数据时也是读取前4个为第一个字段对应的值,读取
第5-54个为第二个字段对应的值。
另外,为便于理解表格与下面内容的关系,特说明字段即是指表格中的列,
记录指表格中的行数据,DBF按行数据方式来存储,即在文件头中定义了列数、
列的名称、列的数据类型、列长度等等,然后在后面的记录数据中插入每行数据。
文件头中格式及说明如下:
位置类型说明
01个字节表示当前的版本信息:
•0x02FoxBASE
•0x03FoxBASE+/DbaseIIIplus,nomemo
•0x30VisualFoxPro:.
•0x31VisualFoxPro,autoincrementenabled
•0x43dBASEIVSQLtablefiles,nomemo
•0x63dBASEIVSQLsystemfiles,nomemo
•0x83FoxBASE+/dBASEIIIPLUS,withmemo
•0x8BdBASEIVwithmemo
•0xCBdBASEIVSQLtablefiles,withmemo
•(orearlier)withmemo
•0xFBFoxBASE
1-33个字节表示最近的更新日期,按照YYMMDD格式,以1900年为
起始,即第一个字节表示文件最后保存时的年份-1900,
第二个字节的值为保存时的月,第三个字节的值为保存
时的日。
4-7Int32文件中的记录条数,即表格的行数。
8-9Int16文件头中的字节数,在此之后的字节为表格记录数据
10-11Int16一条记录中的字节长度,即每行数据所占的长度
12-132个字节保留字节,用于以后添加新的说明性信息时使用,这里
用0来填写。
141个字节表示未完成的操作。
151个字节dBASEIV编密码标记。
16-2712个字节保留字节,用于多用户处理时使用。
281个字节DBF文件的MDX标识。在创建一个DBF表时,如果使用
了MDX格式的索引文件,那么DBF表的表头中的这个字
节就自动被设置了一个标志,当你下次试图重新打开这
个DBF表的时候,数据引擎会自动识别这个标志,如果
此标志为真,则数据引擎将试图打开相应的MDX文件。
291个字节页码标记.
30-312个字节保留字节,用于以后添加新的说明性信息时使用,这里
用0来填写。
32-N(x*32)这段长度由表格中的列数(即字段数,FieldCount)决
个字节定,每个字段的长度为32,如果有x列,则占用的长度
为x*32,这每32个字节里面又按其规定包含了每个字段:.
的名称、类型等信息,具体见下面的表。
N+11个字节作为字段定义的终止标识,值为0x0D。
每个字段定义格式如下表,每个字段定义都用32个字节来完成:
位置内容说明
0-1011个字节字段的名称,是ASCII码值。
111个字节字段的数据类型,为ASCII码值。每个值对应不同的字段
数据类型,如N表示数值,C表示字符串,关于具体的数
据类型说明见下表。
12-154个字节保留字节,用于以后添加新的说明性信息时使用,默认为
0。
161个字节字段的长度,表示该字段对应的值在后面的记录中所占的
长度。
171个字节字段的精度。
18-192个字节保留字节,用于以后添加新的说明性信息时使用,默认为
0。
201个字节工作区ID。
21-3111个字节保留字节,用于以后添加新的说明性信息时使用,默认为
0。
字段数据类型:
代码数据类型允许输入的数据
B二进制型各种字符。
C字符型各种字符。
D日期型用于区分年、月、日的数字和一个字符,内部存
储按照YYYYMMDD格式。
G(GeneralorOL各种字符。
E)
N数值型(Numeric)-.0123456789
L逻辑型(Logical)?YyNnTtFf(?表示没有初始化)。
M(Memo)各种字符。:.
2DBF文件数据结构实例分析
下面以一个具体实例来分析DBF数据结构:
该表格数据为:
列1列2
12
24
36
48
510
612
714
816
918
1020
用UltraEdit打开该dbf文件,其内容如下:
现在先分解一下,找出文件头,并分析一下文件头的内容。首先看第一个
字节,值为03,这个是16进制的数据,第一个字节表示数据库类型,值03即
0x03,对应FoxBASE+/DbaseIIIplus,。然后看第4个字节到第7个字节,这
一段表示文件中的记录条数,即表格的行数,其Byte值为0A000000,转换
成Int32即为10,即表格的行数为10。关于Byte数组转换成数值类型,其代码
如下:
///<summary>
///将字节组转换成为整型
///</summary>
///<paramname="tempBytes">字节数组</param>:.
///<returns></returns>
publicstaticInt32ConvertBytesToInt32(byte[]tempBytes)
{
Int32result=(tempBytes,0);
returnresult;
}
接着看第8个和第9字节,其值为6100,转换成Int16其值即为97,意
思就是说文件头所占字节长度为97,所以文件头的范围就是下面红色框内:
蓝色框为左边红色框对应的值,这个仅供参考。下面来仔细分析红色框中
的数据:
前面的第1个字节到第8个和第9个字节我们前面都已经分析过了。第10
和11个字节对应值表示一行数据的长度,其值为1300,转换为Int其值为19,
即每行数据占19个字节的长度,这个值应该等于接下来定义字段长度之和+1(每
行最前面还有一个16进制值为20的字节)。
接下来的从第12个到31个都为保留字节,可以不管。因为前面已知文件
头的长,为97,而用于文件头定义就占了32个,文件头最后一个字节用于表示
字段定义结束,也占了一个,于是就只剩下97-32-1=64,而每定义一个字段占:.
32个字节,所以就只有2个字段。第一个字段就是从第33个字节开始到第33+32
个字节,如下面黄色框中:
下面参考第三个表来分析这段数据,已知从第0开始到10这11个字节表
示的字段的名称,将这11个字节数组转换成字符串即为字段名称。将字节数组
转换成字符串代码如下:
///<summary>
///将字节组转换成为字符串
///</summary>
///<paramname="tempBytes">字节数组</param>
///<returns></returns>
publicstaticstringConvertBytesToString(byte[]tempBytes)
{
stringresult=
("gb2312").GetString(tempBytes);
returnresult;
}
将第0到第10个字节值转换成字符串,其值为“列1”,即第一个字段的名
称。
第11个字节为字段数据类型,该值为4E(上图中用绿色标出),转换为char
即为N,N表示数值类型,即第一列的数据类型为数值类型。
第12个到第15个为保留字节,暂不管。第16个字节表示字段的长度,其
值为09(上图中用绿色标出),转换为Int其值即为9,即表示该字段长度为9
个字节。后面从第17到31个字节都可暂不管。这样就分析完了一个字段的定义,
安装同样的思路分析第二个字段,可以得到第二字段名称为“列2”,字段类型
也为数值类型(N),字段长度也为9个字节。如下图所示,注意绿色框中的数据::.
在第二个字段定义完成后,接下来的一个字节值为0D,即表示结束了字段
定义,刚好在此也是97个字节。从第98个字节开始就是表格的数据对象了,每
行占19个字节,其中第一个字节值为20,不属于表格单元的值,即从第99个
字节开始,前面9个字节对应的值为第一行第一列单元的值,接着的9个字节是
第一行第二列单元的值,在接下来的一个字节为默认字节,接着的9个字节就是
第2行第一列单元的值,接下来的9个字节就是第2行第2列单元的值,依次类
推,直到结束位置。
3DBF文件读取与写入程序设计
下面介绍使用程序来读取和写入DBF文件:
首先新建一个窗体项目,各主要控件如下图所示:

读取DBF文件的内容并写到一个DataGridView控件中,采用如下函数:
///<summary>:.
///读取DBF文件
///</summary>
///<paramname="filepath">DBF文件路径</param>
///<paramname="dataGridView">DataGridView控件</param>
privatevoidReadDBFFile(stringfilepath,DataGridViewdataGridView)
{
try
{
();
();
//打开文件
FileStreamfs=newFileStream(filepath,,
);
BinaryReaderbr=newBinaryReader(fs);
//跳过前面4个
(4);
//文件中的记录条数,即行数
introwCount=();//4
//文件头的长度
intheadLength=();//2
//每行的长度
introwLength=();//2
//计算字段数目
intcolumnCount=(headLength-33)/32;
//跳过32-4-4-2-2=20个,直接到32
(20);
inti,j;
byte[]tempBytes=null;
bytetempByte;
int[]fieldLength=null;
//添加表格的列
if(columnCount>0)
{
stringtempColumnName;
fieldLength=newint[columnCount];
for(i=0;i<columnCount;i++)
{
//读取前11个,为列名称
tempBytes=(11);
tempColumnName=ConvertBytesToString(tempBytes);
(tempColumnName,:.
tempColumnName);
//跳过5个
(5);
//获取字段长度
tempByte=();
fieldLength[i]=(int)tempByte;
//跳过剩下的字节,有32-11-5-1=15个
(15);
}
}
//获取文件头的最后一个字节,值应该为0D
tempByte=();
if(tempByte==0x0D)
{
//添加表格的行及数据
if(rowCount>0)
{
stringtempStr;
for(i=0;i<rowCount;i++)
{
();
//每行数据中第一个20,跳过
();
for(j=0;j<columnCount;j++)
{
tempBytes=(fieldLength[j]);
tempStr=ConvertBytesToString(tempBytes);
dataGridView[j,i].Value=tempStr;
}
}
}
}
else
{
("文件头定义出现错误!",
"提示!",,);
}
();
();
}
catch(Exceptionexcept)
{
(,
"提示!",,);:.
}
}
///<summary>
///将字节组转换成为字符串
///</summary>
///<paramname="tempBytes">字节数组</param>
///<returns>DataGridView控件</returns>
publicstaticstringConvertBytesToString(byte[]tempBytes)
{
stringresult=
("gb2312").GetString(tempBytes);
returnresult;
}
///<summary>
///将字节组转换成为整型
///</summary>
///<paramname="tempBytes">字节数组</param>
///<returns></returns>
publicstaticInt32ConvertBytesToInt32(byte[]tempBytes)
{
Int32result=(tempBytes,0);
returnresult;
}
所以,在按钮“读取DBF文件button1”的单击事件添加调用上面读取DBF文件
的代码:
privatevoid读取DBF文件button1_Click(objectsender,
EventArgse)
{
if(())
{
ReadDBFFile(,dataGridView1);
}
}

同样,编写用于存储DBF文件的函数,如下:
///<summary>
///保存DBF文件
///</summary>
///<paramname="filepath">DBF文件保存路径</param>
///<paramname="dataGridView">表格对象</param>
privatevoidWriteDBFFile(stringfilepath,DataGridViewdataGridView):.
{
try
{
introwCount=;
intcolumnCount=;
if(rowCount>0&&columnCount>0)
{
FileStreamfs=newFileStream(filepath,,
);
BinaryWriterbw=newBinaryWriter(fs);
bytetempByte;
byte[]tempBytes;
inti,j,tempInt;
int[]fieldLength=newint[columnCount];
inttempMax=0;
for(i=0;i<columnCount;i++)
{
tempMax=0;
for(j=0;j<rowCount;j++)
{
if(dataGridView[i,j].Value!=null
&&dataGridView[i,j].()!="")
{
if(dataGridView[i,
j].().Length>tempMax)
{
tempMax=dataGridView[i,
j].().Length;
}
}
}
fieldLength[i]=tempMax*2;
}
//写入文件头
{
//第0个字节为数据库类型
tempByte=0x03;
(tempByte);
tempBytes=newbyte[3];
//第1个字节为保存时的年份-1990:.
tempInt=-1900;
tempBytes[0]=(tempInt);
//第2个字节为保存时的月份
tempBytes[1]=
();
//第3个字节为保存时的日
tempBytes[2]=(byte)();
(tempBytes);
//第4-7个字节为行数
(rowCount);
//第8-9字节为文件头的长度
tempInt=33+columnCount*32;
((Int16)tempInt);
//第10-11为每行数据所占长度
tempInt=1;
for(i=0;i<columnCount;i++)
{
tempInt+=fieldLength[i];
}
((Int16)tempInt);
//第12-31为保留字段,默认为0
tempBytes=newbyte[20];
(tempBytes);
stringtempColumnName;
//开始写字段
for(i=0;i<columnCount;i++)
{
tempColumnName=[i].Name;
tempBytes=ConvertStringToBytes(tempColumnName,
11);
(tempBytes);
//第11个字节为数据类型
tempByte=(byte)('C');//数据类型为字符串
(tempByte);
//第12-15为保留字节
tempBytes=newbyte[4];
(tempBytes);
//第16个字节为字段长度
tempByte=(byte)fieldLength[i];:.
(tempByte);
//接着第17-31都为保留字节
tempBytes=newbyte[15];
(tempBytes);
}
//最后以0D结尾
tempByte=0x0D;
(tempByte);
}
objecttempValue;
//写入单元格数据
for(i=0;i<rowCount;i++)
{
//每一行第一个字节默认为20
tempByte=0x20;
(tempByte);
for(j=0;j<columnCount;j++)
{
tempValue=dataGridView[j,i].Value;
if(tempValue!=null)
{
tempBytes=
ConvertStringToBytes((),fieldLength[j]);
(tempBytes);
}
else
{
tempBytes=ConvertStringToBytes("",
fieldLength[j]);
(tempBytes);
}
}
}
();
();
}
else
{
("表格中没有数据",
"提示!",,);
}:.
}
catch(Exceptionexcept)
{
(,
"提示!",,);
}
}
///<summary>
///将字符串转换成为字节数组
///</summary>
///<paramname="tempStr"></param>
///<paramname="limitLength"></param>
///<returns></returns>
publicstaticbyte[]ConvertStringToBytes(stringtempStr,int
limitLength)
{
byte[]result=null;
byte[]tempBytes=
("gb2312").GetBytes(tempStr);
if(==limitLength)
{
result=tempBytes;
}
elseif(>limitLength)
{
for(inti=0;i<limitLength;i++)
{
result[i]=tempBytes[i];
}
}
elseif(<limitLength)
{
result=newbyte[limitLength];
for(inti=0;i<;i++)
{
result[i]=tempBytes[i];
}
}
returnresult;
}
同样,在按钮“保存DBF文件button1”的Click事件中添加调用上面的函
数:
privatevoid保存DBF文件button1_Click(objectsender,EventArgse):.
{
SaveFileDialogsaveDg=newSaveFileDialog();
="保存DBF文件";
="DBF文件(*.dbf)|*.dbf|所有文件(*.*)|*.*";
if(()==)
{
WriteDBFFile(,dataGridView1);
}
}

DBF文件格式详细说明及程序设计 来自淘豆网m.daumloan.com转载请标明出处.

非法内容举报中心
文档信息
  • 页数15
  • 收藏数0 收藏
  • 顶次数0
  • 上传人小s
  • 文件大小477 KB
  • 时间2022-11-30
最近更新