分享

自动恢复损坏的FoxPro文件

 Alkaid2015 2012-11-10

自动恢复损坏的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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多