自动恢复损坏的FoxPro文件
出处:网络
运行FoxPro语言编写的应用软件时,可能会发生数据库文件损坏的情况。由于在FoxPro中,对数据库文件的所有操作,都
是在成功打开数据库文件之后进行的,所以一旦数据库文件损坏,应用软件将无法运行。对于一般使用应用软件的用户,可能并不具备计算机的专业知识。这就需要
在应用软件中,采用可以自动恢复损坏的数据库文件的方法。
·设计思想·
要做到自动恢复损坏的数据库文件,具体步骤为:
A.在数据库文件完好时,备份正常的数据。
B.在程序运行时,随时侦查损坏的数据库。
C.使用备份数据,自动恢复损坏的数据库文件。这三个步骤,都需要编制相应的应用程序。在编制这些应用程序时,应该考虑:
1.可能发生硬盘损坏,或因病毒破坏严重(尤其单机用户),需对硬盘重新格式化之后,进行数据恢复,所以应使用软盘进行数据备份。使用软盘进行数据备
份,应保证备份的数据可靠、完整,而无重复。数据的丢失或重复,都将对恢复的数据库文件造成不正确的结果。
2.备份软盘的数量。为防止备份软盘可能损坏,在进行数据备份时,应做到至少备份两份数据。另外,为保证硬盘重新格式化之后的数据恢复,应向用户提供两份应用程序和初始化数据的软盘。
3.备份数据的确定。应在初始化数据中,设置一个存放数据库文件名的文件。这个库名文件(ffile)中有两个字段:filename(需要备份的数
据库文件名),filetext(数据库的中文名称,用于显示)。根据其指定的文件名,进行备份。当侦查到数据库文件损坏时,可作为自动定位的依据。另
外,当需要增加或变更备份的数据库文件时,修改这个库名文件中的记录,比修改应用程序灵活、简便。
4.备份数据的日期范围。应仅备份上次备份之后录入的数据,不必每次都备份全部数据。这就要求设置一个存放日期的文件,以保证备份数据连续完整,而无
重复。这个日期文件(fdate)中有三个字段:bgndate(软件正式运行日期),credate(备份数据截止日期),apedate(恢复数据截
止日期)。为此,要在每个需要备份的数据库文件中,记录数据录入的日期,以便从数据库中截取每次需要备份的记录。
在每次备份数据时,应以上次截止日期的第二天为起始日期,以当天的前一天为截止日期。当天的数据不应备份,因为当天可能还要录入新的数据。并将起始日期和截止日期也存入软盘备份文件中,以保证恢复数据的连续完整,而无重复。
5.软盘备份文件的格式。应采用文本文件格式,而不采用记录格式,以免记录格式丢失,造成记录无效。这个文本文件的一般形式如下,各行的内容为:
本次备份数据的起始日期、截止日期
第一个数据库备份的记录个数、库文件名、中文名称
第一个数据库备份的第一个记录
……
第一个数据库备份的最后一个记录
第二个数据库备份的记录个数、库文件名、中文名称
第二个数据库备份的第一个记录
……
第二个数据库备份的最后一个记录
……
使用备份起始日期作为软盘文件的文件名,形式为“yyyymmdd.txt”。这个文件名起到邮戳的作用,将其写在软盘的标签上。它一方面用于区别软
盘上存放的多个备份文件;另一方面为恢复数据时,顺序查找相应的软盘备份文件提供方便。在恢复数据时,以备份文件中的截止日期加1,作为下一个恢复文件的
文件名,查找备份文件。所以不应以截止日期作为软盘文件的文件名,否则很难实现顺序地查找备份文件。
在恢复数据时,应以软件正式运行的日期,作为第一个恢复文件的文件名,查找备份文件。并在每次恢复数据之后,更新日期文件中恢复数据的截止日期。
6.在恢复数据时,应仅恢复损坏的数据库文件。正常的数据库文件,不需要也不应当进行恢复。为此,在恢复数据库文件的程序中,应能自动判定哪些数据库文件是损坏的。
7.在恢复数据时,应先恢复数据库文件的库结构,再恢复数据。文件的库结构存放在初始化数据软盘中。
8.自动侦查数据库文件损坏的出错处理程序,应设置在主程序中。一个完好的应用软件,应做到无算法错误,所以在出错处理程序中,只处理物理错误。在FoxPro中,物理错误造成的结果,主要是数据库文件损坏。
·实现方法·
本文使用FoxPro语言编制的程序中,用《自然语言》表示伪码。读者在使用这些应用程序时,对程序中的伪码部分,可根据读者的编程习惯,变换成具体的命令语句。
1.《主程序》中的相关部分:
在主程序中,设置控制参数:例如,set talk off,set safety off,等等。设置on error do
ferror。然后是主程序中的其他部分:例如,主菜单,各个功能模块的调用(包括生成备份数据模块),以“广播结束”方式(set
clear off)显示未做备份的天数date()-credate,等等。这里,ferror是侦错处理程序:
procedure ferror
《 提示:数据库文件损坏。按任意键进行恢复。》
rtnkey = inkey(0)
do 《恢复数据库》
return
2.《恢复数据库》的应用程序:
(1)损坏的数据库文件自动定位:
《提示:正在检查数据库文件, 请稍候…》
use ffile && 打开库名文件
fcount = reccount() && 库名文件个数
dimension hname(fcount) && 存放库名的数组
for i=1 to fcount
hname(i)=space(8)
endfor
on error do herror && 检测损坏的数据库
hcount = 0
do while !eof()
tname = filename && 库文件名
ttext = filetext && 库文件中文名称
file0 = trim(tname)
select 0
use &file0 index &file0 && 损坏,执行herror
use
select ffile
skip
enddo
if hcount = 0
《提示:文件完好,程序有其他错误,按任意键退出。》
rtnkey = inkey(0)
quit
endif
这里,herror是检测处理程序:
procedure herror
hcount = hcount + 1
《显示损坏的数据库文件的中文名ttext》
hname(hcount) = tname && 保存损坏的库名
return
(2)提示用户插入初始数据软盘。检查指定驱动器
(tinp)中,有无初始数据软盘。正确后进行数据恢复:
《提示:正在恢复数据库文件结构, 请稍候…》
for i=1 to hcount && 选择需恢复的数据库文件
file1 = trim( hname(i) )
tname = tinp+':\'+file1 && 软盘中的库文件
select 0
use &tname index &tname && 打开软盘文件
tindex = sys(14,1) && 获取文件索引
copy to &file1 && 恢复库结构
use &file1
index on &tindex to &file1 && 建立索引
use
endfor
《提示:数据库文件结构已经恢复。》
select 0
use fdate && 打开日期文件
repl apedate with bgndate-1 && 截止日期初值
do while .t.
tsdate1 = apedate+1 && 软盘备份文件的邮戳
file2 = tinp+':\'+substr(dtos(tsdate1))+'.txt'
《提示:插入名为file2软盘,按任意键继续。》
rtnkey = inkey(0)
《检查软盘,正确后继续。》
《提示:正在恢复数据, 请稍候…》
create dbf ftext ( rectext c (130) )
*/ 建立缓存数据库,记录长度可视需要设定。
append from &file2 sdf && 读入整个文件
go top && 文件第一行
tsdate2=ctod(substr(rectext,1,8)) && 起始日期
tedate2=ctod(substr(rectext,9,8)) && 截止日期
《显示:本次恢复数据的起止日期。》
skip
do while !eof()
tcount=val(substr(rectext,1,8)) && 记录个数
tname=substr(rectext,9,8) && 库文件名
ttext=substr(rectext,17,12) && 中文名称
skip
copy to 'tmp' next tcount sdf && 文件记录
file3 = space(8)
for i=1 to hcount
if tname = hname(i)
file3 = tname && 匹配数据库文件名
exit
endif
endfor
if file3 # space(8)
《显示中文名称ttext,记录个数tcount》
file3 = trim(tname)
select 0
use &file3 index &file3
append from 'tmp' sdf
use
endif
select ftext
skip
enddo
select fdate
if credate = tedate2
exit && credate为备份数据截止日期
endif
repl apedate with tedate2 && 更新截止日期
enddo
《提示:数据库文件已经恢复, 按任意键重新运行。》
rtnkey = inkey(0)
quit
|