| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1550 人关注过本帖, 1 人收藏
标题:VFP探讨之空值和可变长类型在DBF表文件中的存储(三):空值和可变长数据的跟 ...
只看楼主 加入收藏
taifu945
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:80
帖 子:1545
专家分:3298
注 册:2012-7-6
结帖率:100%
收藏(1)
 问题点数:0 回复次数:1 
VFP探讨之空值和可变长类型在DBF表文件中的存储(三):空值和可变长数据的跟踪
    在FoxPro中,可变长数据除了之前提到的Varchar以外,还有Varbinary,本次讨论统称可变长类型。
    .NULL.值和可变长类型的跟踪依靠一个隐藏字段,它的名字是“_NullFlags”。该字段无需人为添加,会自动根据表文件的字段情况添加或删除。它出现的前提是:表文件中至少包含一个允许.NULL.值的字段,或一个可变长类型。也就是说,表文件中如果没有一个字段允许.NULL.值,且没有一个字段是可变长类型时,它不会出现。_NullFlags字段无论是否存在于表文件中,我们通过常规的FoxPro命令都是无法看到和使用它的。它的初始宽度为1个字节,也就是8个二进制位,随着需求量的增长或减少,它会自动以1个字节为单位扩充或缩减宽度。既然是一个字段,那就拥有与普通字段相同的功能 — 每条记录都在该字段上存在一个值。
    _NullFlags字段值的作用有两个:1)跟踪当前记录在相应字段上是否为.NULL.值;2)跟踪当前记录在各个可变长类型字段中是否已经填满了设计宽度。对于一个仅是可变长类型的字段,占用其中的1位,“0”表示已占满了字段的设计宽度,“1”表示未占满字段的设计宽度;对于一个仅允许.NULL.值的字段,也只占用其中的1位,“0”表示内容不为.NULL.,“1”表示内容为.NULL.;对于一个既是可变长类型,又允许.NULL.值的字段,需要占用_NullFlags字段值的2位:高位代表着是否为.NULL.值,低位代表着是否占满了字段的设计宽度。高位和低位中“0”和“1”的意义与上面介绍的相同;其它既不是可变长类型,又不允许.NULL.值的字段不占用_NullFlags字段值的位数。排列在前的字段占用_NullFlags字段值的低位(右边),排列在后的字段占用它的高位(左边)。
    例:现在有一个表,结构如下图:
图片附件: 游客没有浏览图片的权限,请 登录注册

其中的值如下图:
图片附件: 游客没有浏览图片的权限,请 登录注册

    在两张图片中,绿框框起的是仅允许包含.NULL.值的字段,这种字段占用_NullFlags字段值中的1个二进制位;红框框起的是既具有可变长类型,又允许包含.NULL.值的,具有双重性质的字段。这种字段占用_NullFlags字段值中的2个二进制位。本例的表文件一共需要占用_NullFlags字段值中的6个二进制位,所以,该字段只要初始的一个字节就够用了。
    根据前面讲到的,排列在前的字段占用_NullFlags字段值的低位,排列在后的字段占用高位。那么,本例中_NullFlags字段值的右边第1位被FF1字段占用;右边第2位被FF2字段占用;右边第3位被FF3字段占用;右边第4、5位被FF4字段占用;左边第3位(即右边第6位)被FF6字段占用。FF5字段因其既不是可变长类型,又不允许包含.NULL.值,所以不占用_NullFlags字段值。下面以表格形式来说明各字段与_NullFlags字段值的关系(表格中直接标注十六进制和二进制的底层数据):
图片附件: 游客没有浏览图片的权限,请 登录注册

    这张表咋一看,头比较晕,很正常,这就是底层数据要达到的效果。 在分析底层数据之前先对这张表略作说明:1)颜色对位:普通字段中数据的文字颜色对应_NullFlags字段值各位的背景色(FF5字段除外);2)高位与低位:同一字节中,左边是高位,右边是低位。比如:FF1下面第一条记录中的数值46,高位是4,低位是6;不同字节中,左边是低位,右边是高位。比如:FF4下面第一条记录中的“41 42”,41是低位,42是高位;有分行的,上行是低位,下行是高位。比如:FF3、FF6下面各条记录。
    我们对照直观数据来分析这张表中几条具有代表性的记录:
    第一条记录:直观数据分别是“.NULL.”、“.NULL.”、“{2013-3-2}”、“AB”、未赋值、“{2013-3-11 10:10:10}”。FF1字段是逻辑型,.NULL.值时保存的是字母“F”的ASCII码,且_NullFlags字段值右边第一位置1,表示这个“F”是.NULL.,而不是逻辑非(这就是FoxPro采用的跟踪技术);FF2字段是数值型,.NULL.值时保存的是数值0,同时,在_NullFlags字段值右边第二位置1,表示这个0不是数学意义上的0;FF5字段不占用_NullFlags字段值的位置,其它字段都是正常状态。所以,_NullFlags字段值在该条记录上从右边第三位到左边第一位都是0,最终形成00000011,故,DBF文件中保存为十六进制的03。
    第四条记录:直观数据分别是“T”、“0”、“.NULL.”、“.NULL.”、未赋值、未赋值。FF3字段是日期型,.NULL.值时保存的是8个空格的十六进制ASCII码值20,同时,_NullFlags字段在其对应的右边第三位置1;FF4字段是可变长类型,又允许.NULL.值。鉴于这些性质,它需占用_NullFlags字段值的两位(本例中它占用右边第四、五位)。由于第四条记录的FF4字段值是.NULL.,所以,_NullFlags字段值的右边第五位置1,且FF4字段值第一字节填充空格的十六进制ASCII码20,第二字节填充数值0(表示没有任何有效字符);对于可变长类型来说,值为.NULL.就是不足设计宽度(哪怕这个字段的设计宽度仅为1),因此_NullFlags字段值的右边第四位也要置成1,剩下的其它字段都不影响_NullFlags字段值。综上所述,在这条记录上,_NullFlags字段值就是00011100,也就是十六进制的1C。
    以上讨论的内容可以用一个FoxPro 9.0自带的小工具来观察验证。这个工具叫HexEdit,文件名是HexEdit.app,位于FoxPro 9.0安装目录下的“\Tools\HexEdit”文件夹中,在命令窗口中用语句DO HOME()+"\Tools\HexEdit\HexEdit"来调用。成功调用该工具后会弹出一个“打开”对话框,要求确定需要观察的文件名,选择好文件并点击“确定”钮就可以打开相应文件了。
    以下是刚刚讨论的案例截图,有兴趣的可以研究一下:
图片附件: 游客没有浏览图片的权限,请 登录注册

    绿框是第一条记录的数据,其中左边是底层数据,右边是相应字符,相当于CHR(左边数值)(下同);蓝色框是第二条记录;咖啡色框是第三条记录;粉色框是第四条记录;桔色框是第五条记录。各记录末尾用红色框框起的就是_NullFlags字段值。


[ 本帖最后由 taifu945 于 2014-3-27 16:47 编辑 ]
2014-03-27 16:43
klise
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2013-12-19
收藏
得分:0 
非常感谢,写得很详细,我还要花时间慢慢琢磨,呵呵。
2016-04-24 15:57
快速回复:VFP探讨之空值和可变长类型在DBF表文件中的存储(三):空值和可变长数据 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029087 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved