4.为Delphi提供Pack和Undelete功能
weiwu
本文针对Delphi3和Delphi4,对于C++Builder同样也适用,在数据库引擎BDE4.0、4.5、5.0中经过测试。
Delphi目前已经是国内常见的数据库编程工具,它在各方面表现不错,在支持大型多层数据库结构的同时也完全支持本地数据库的支持。对于本地数据库中Delphi对FoxPro2.5b的支持也不错,我曾经对VB、FoxPro2.5b、Delphi的数据库操作速度进行比较,发现除了启动速度较慢外,其它各项Delphi均排在首位。而且Delphi几乎支持所有原先FoxPro所拥有的功能,对于有一定编程经验的人来说,Delphi成了编写数据库软件的一把利器,因而Delphi迅速流行起来,我几年前甚至利用Delphi 1.0和汇编配合制作了工业控制系统的实时前后台软件。
但是在我长期使用Delphi编程的过程中发现它也有不如人意的地方,特别是在本地数据库FoxPro方面,它居然不支持十分有用的Pack和Undelete功能。对于数据库来说,因为是一个顺序存储文件,在删除部分记录是一般采用了软删除技术,也就是说将要删除的记录标记已删除的标记,但并不立即从物理上删除这些记录。这样做可以避免仅仅删除一条记录就要将整个数据库重新写入存储器,提高了读写的效率。但是如果数据库长期不对已经被标记为删除的记录进行整理和真实删除,数据库就会越来越大,其中无用的数据所占的比率越来越大,使得数据库的读写效率迅速下降,而且造成查询速度的减慢。在编写FoxPro数据库时有个规律,如果数据进出数据库频繁,也就是说不断删除旧的数据,加入新的数据的情况下每次在关闭数据库的时候或打开数据库的时候先做一次Pack,对数据库进行整理,将软删除的记录真正从数据库中删除。但是在Delphi的各个版本中数据库控件均未提供Pack的功能,这使得用Delphi编写的数据库软件如果使用本地数据库的形式,数据库的大小增长很快,即使删除了大量记录,数据库的大小没有任何改变。以前我的做法是在使用这类数据库软件一段时间后利用FoxPro打开数据库进行Pack,但是这样做要求客户端拥有FoxPro,而且经常这么做也很繁。于是我开始查找有关资料,为什么Delphi无法使用pack功能?
经过再三查找,我找到一些资料,说明如何对数据库进行pack了,在将其改编后在Delphi中使用通过。下面是其中的核心程序。
BDE API Call:
DBIResult DBIFN DbiPackTable (hDb, hCursor, pszTableName, [
pszDriverType], bRegenIdxs);
在数据库引擎的底层函数调用中,我找到了这个函数,这个函数据说可以对FoxPro的数据库进行Pack,其中hDb是数据库的句柄,可以由Table.Handle获得;hCursor是数据表(Table)关联的游标,如果为NULL则数据表依赖于pszTableName和pszDriverType这两个传输决定数据库的来源;bRegenIdxs决定是否关联外接的索引文件尤其是MDX多索引文件。
具体的操作函数如下:
procedure PackTable(Table: TTable);
var
Props: CURProps;
hDb: hDBIDb;
begin
if not Table.Active then
raise EDatabaseError.Create('Table必需已经打开');
if not Table.Exclusive then
raise EDatabaseError.Create('Table必需以独占方式打开');
Check(DbiGetCursorProps(Table.Handle, Props));
if (Props.szTableType = szDBASE) then
Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))
else
raise EDatabaseError.Create('Table必需是dBASE或FoxPro类型');
Table.Open;
end;
特别对这段源码说明一下,这段源码部分改编自C,已经在上面提到过的环境中测试通过,需要注意的是,数据表必需以独占方式打开,简单的说,就是在设计时将数据表关闭(属性Active=False),在运行时才打开数据表(form_onCreate时Table.Open),这样才能保证数据表在独占方式下被打开。DbiGetCursorProps()是一个读取数据表的属性的底层函数调用,返回了大部分通用的数据表属性。Check()函数可以简单的处理数据库的出错提示和异常处理,如果出现函数调用错误会自动显示出错信息。
说了pack那么与之对应的Undelete也就更要解释了,同样我找到了将软删除的数据恢复的函数,不过这个函数隐藏的更深,连C代码都没有,所以以下的代码完全由我自己摸索出来,仅在上面说到的环境中测试通过。
首先介绍一下相应的底层函数调用:
DBIResult DBIFN DbiUndeleteRecord (hCursor);
这个函数仅有的参数就是关联的数据表的游标,您可以在BDE.int的文件中找到它的声明,但是具体的使用说明含糊不清,到底是恢复当前被删记录还是将数据表内所有被软删除的记录全部恢复?由于缺少相应的代码分析,我参照FoxPro的经验进行了多次实验,在十几种方案的对比下得出了结论,这条函数调用仅仅恢复当前的被软删除的记录。因此必需首先将数据表的游标移动到被删除的记录上,然后调用这条函数,才会有所反应。要知道在默认的情况下,数据库控件是不会将游标移动到被删除的记录上的,所以必需首先将数据表的读写属性修改,打开软删除的属性,使得遍历数据表时可以访问到被标记为删除的记录。下面是一段实现将数据表中所有被软删除的记录恢复的源代码。其它形式的反删除可以参照这段代码。
procedure Ttablepro.undelete;
var
CProps: CurProps;
rslt: DBIResult;
bm:TBookmark;
rp:pRECProps;
begin
Check(DbiGetCursorProps(self.Handle, CProps));//取得数据表的属性
if (StrIComp(CProps.szTableType, szDBASE) <> 0) then//如果不是Dbase或Foxpro则退出
raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);
rslt:=DbiValidateProp(hDBIObj(self.Handle), curSOFTDELETEON, True);
//可否设置软删除?
if (rslt = DBIERR_NONE) then
Check(DbiSetProp(hDBIObj(self.Handle), curSOFTDELETEON, Longint(true)));
//设置为可以软删除
Check(DbiGetCursorProps(self.Handle, CProps));
//更新数据表的属性
if (CProps.bDeletedOn = False) then
raise EDatabaseError.Create('软删除没有设置!');
//取得当前的记录位置
bm:=self.GetBookmark;
//将游标移动到第一个记录以前!Not Table.First!
Check(DbiSetTobegin(self.handle));
//不断移动,直到到数据表的最后记录
while (DBIGETNEXTRECORD(self.handle,dbinolock,nil,nil)=DBIERR_NONE) do
begin
//请关闭Delphi的异常响应,以便执行下面的语句!
try
check(DbiUndeleteRecord(self.Handle));
except
//Do somthing here !
end;
end;
//取回原先记录的位置,重新定位
self.GotoBookmark(bm);
self.FreeBookmark(bm);
self.Refresh;
end;
(注:如果可以,请在刊登时删去“Self.refresh”一行,对于原理的介绍无需此行,仅在我的控件的属性中需要,以上代码来自我制作的Delphi控件TTablePro)
分享到:
相关推荐
9. 其他恢复工具:除了"Undelete"之外,还有许多类似的工具,如Recuva、EaseUS Data Recovery Wizard等,它们都提供类似的服务,用户可以根据自身需求选择合适的产品。 10. 法律与道德:请注意,非法恢复他人已删除...
【描述】"xfs_undelete-master" 提示这是一个专注于XFS文件系统恢复功能的主项目或代码库。"undelete"通常是指在文件被误删后尝试恢复的功能。因此,这个项目可能包含了源代码、脚本或者其他工具,使得用户能够在XFS...
● 通过Office版本保护功能恢复旧版本的Word、Excel和PowerPoint文件。 ● 支持64位操作系统,包括Windows Vista和Windows Server 2008。 ● 磁盘搜索技术(Search Disk):搜索并恢复被删除的文件。 ● 紧急恢复技术...
此外,软件还提供了日志记录和报告功能,以便用户追踪恢复过程和结果。 在使用Active Undelete 8时,用户界面友好且直观,无论是新手还是经验丰富的用户都能轻松上手。软件提供了详尽的用户指南和在线帮助,对于...
本文将深入探讨undelete_plusun的原理、功能、使用方法以及在实际操作中的注意事项,旨在为用户提供全面的恢复策略和数据保护建议。 undelete_plusun是一款专业的删除恢复软件,它的主要功能是找回被误删或因其他...
Undelete360 是款俄罗斯出品的绿色免费快速小巧的数据恢复软件,比FinalData好用多了,至少速度快 N 倍,而且是安全免费的软件哦!...它是完全免费为你使用和享受。 缺点:对视频类文件支持有限,仅支持.swf文件。
Glary Undelete是一款强大的数据恢复软件,专为恢复硬盘、随身碟、记忆卡以及外接磁碟上被误删或丢失的文件而设计。它支持多种档案系统,包括常见的FAT(File Allocation Table)和NTFS(New Technology File System...
尽管体积小巧,但它的功能却一点也不逊色,能够有效地帮助用户找回那些被误删除的文件,为用户提供了一道数据安全的防线。 在描述中提到,"undelete_plus_2.51"不仅可以恢复常规删除的文件,就连那些通过清空回收站...
总的来说,undelete_plus作为一款优秀的数据恢复工具,不仅提供了强大的恢复功能,还以其便捷的操作和良好的用户体验赢得了用户的青睐。对于个人用户和小型企业来说,它是应对数据丢失问题的一个可靠选择。然而,...
总的来说,undelete_plus2.9.8.0是一款不可多得的文件恢复工具,它以简洁的界面、强大的功能和免费的服务,为误删文件的用户提供了便捷的解决方案。对于那些需要频繁处理重要数据的人来说,了解并掌握这款软件的使用...
这两者都是“Easy Undelete”提供的服务,它能帮助用户找回意外删除的重要文件,无论是文档、图片、视频还是其他类型的文件。 在实际使用“Easy Undelete”时,用户首先需要启动软件,然后按照向导进行操作。软件...
此外,"Undelete.2009.Professional.v6.0.157"还提供了一套完整的文件过滤和分类机制。用户可以根据文件类型、大小、修改日期等条件进行筛选,快速定位目标文件。对于大型硬盘,这一特性尤为实用,大大节省了恢复...
6. **Undelete.cpp**:可能是整个恢复功能的核心实现,包含了文件恢复算法和主要函数。 7. **FindDlg.cpp**:可能是一个用于查找特定文件或文件夹的对话框的实现。 8. **StdAfx.cpp**:预编译头文件,用于加速编译...
Undelete 360是一款简单易用功能强大的数据恢复软件 1、可以恢复本地磁盘、数码相机、软盘、U盘的数据; 2、恢复意外删除的文件和文件夹、恢复因病毒引起的文件丢失; 3、恢复因删除文件时因文件太大没有以过...
总的来说,Undelete Plus 2.98是一款值得信赖的数据恢复软件,它以其高效、易用和全面的功能,为用户提供了强有力的保障。不论你是个人用户还是企业用户,面对误删文件的困境,这款绿色免费版的Undelete Plus 2.98都...
更另人惊喜的是undelete 360体积小巧 ,完全免费,没有任何广告和功能限制! 可以恢复本地磁盘、数码相机、软盘、U盘的数据; 恢复意外删除的文件和文件夹、恢复因病毒引起的文件丢失; 恢复因删除文件时因文件太大...
它提供了丰富的功能来读取、写入、修改和管理这些类型的数据库文件。TDbf 控件非常适合那些需要在应用程序中集成 dBase 数据库支持的开发人员。 #### 二、类结构 TDbf 的类结构主要由以下几个部分组成: - **TDbf...
在找到丢失的文件后,undelete plus提供预览功能,让用户确认文件内容是否正确,避免恢复错误的文件。用户可以选取需要恢复的文件,指定恢复后的保存位置,确保不覆盖其他可能的重要数据。值得注意的是,为了提高...