| 文章: |
摘要:实际应用中,由于断电或不正常关机等其他因素,我们发现辛辛苦苦创建或花几天工夫录入的FoxPro 数据库被破坏,每次打开它时,都出现 “Not a table /DBF file ”的提示。原因是该数据库有不正确的表头,在FoxPro 中不能打开它,重要的数据因而也读取不出来。实践中我们发现用FoxBase 能打开这种被破坏的数据库。
链接:http://www2.ccw.com.cn/tips/9907/072102_04.asp
曾川闽的意见:
这个办法有时也不行,数据文件损坏严重时,用EXCEL或FOXBASE可能都无法打开文件,但近时我在处理这个问题时在乱试时发现用ACCESS可以解决,办法是新建一个空的MDB文件,在新建表时选导入,把损坏的DBF文件导入MDB文件,数据竟然都恢复了。
在你面前的意见:
如果是只用VFP本身提供的功能,而不用其他任何工具可能恢复情况会好些。本人经过反复实验发现数据库被破坏的原因是在断电或不正常关机之前追加了记录,然后才是其他因素。可以用以下代码修复,前提是在该表有备份文件(即 .bak文件)或者是该表在未被破坏之前有一个拷贝。假如被破坏表名为:aaa.dbf,在未被破坏之前有一个拷贝表名为aaa2.dbf。代码如下:
SET SAFETY OFF
COPY FILE aaa.bak TO aaa1.dbf &&或将aaa.bak 改为aaa2.dbf
USE "aaa1.dbf" EXCL
ZAP
APPE FROM aaa.dbf
CLOSE ALL
COPY FILE aaa1.DBF TO aaa.dbf
金子光的意见:
fox损坏,是fox追加记录后fox库的头己有记载,但这时内容还在缓冲区里未写入磁盘,此时掉电,在再开机打开fox库时,fox要检查记录是否和文件长度匹配,如不相符则认为不是fox库,本人在dos时代用fox自身,写过一个程序,用于损坏的fox库修复,此程序在visual foxpro 8.0里也可使用.程序符在下面:
* foxpro 库修复
procedure redbf
fname=space(20)
@10,10 say "需要修复fox库,请输入文件名 [ESC]返回" get fname size 1,20 defa" "
READ
if not empty(fname)
fname=rtrim(fname)
if not ".dbf"$fname
fname=fname+".dbf"
endif
do redatabs with fname
endif
*restor screen from scr
return
procedure redatabs
para fname
fa=0
fa=fopen(fname,2) && 打开文件,读写方式
if fa=-1
WAIT window fname+"文件打开错误"
return
endif
s= asc(fread(fa,2)) && 读fox库标志
d=fseek(fa,4)
l=4
rec=jread() && 读四字节换算为记录数
l=2
hd=jread() && 读二字节换算为fox库文件头长度
l=2
lrec=jread() && 读二字节换算为记录长度
flenght=rec*lrec+hd && 计算fox库文件总长度
fl=fseek(fa,flenght,0) && 将指针移到文件尾
=fwrite(fa,chr(26),1) && 写文件结束标记
fl=fseek(fa,0,0) && 将指针移到文件头
=fwrite(fa,chr(03),1) && 写FOXPRG文件标志
fl=fseek(fa,29,0)
=fwrite(fa,chr(0),2)
= fclose(fa) && 关文件
use &fname excl && 此时库文件已可使用
appe blank && 增加一笔空记录再删除是为了使库可用也可不做
dele
PACK && 你的库如要保留删除记录请不要用此命令
wait window " 文件名="+fname+" "+chr(13)+chr(10)+;
" 头长度="+str(hd,7)+chr(10)+chr(13)+;
" 记录长="+str(lrec,7) +chr(10)+chr(13)+ ;
" 记录数="+str(rec,7) +chr(10)+chr(13)+ ;
" 文件长="+str(flenght,9) +chr(10)+chr(13)+ ;
" 库修复完毕,请继续使用" nowait
REINDEX && 重新索引
&& 修复后的库,最后几条记录是掉电或不正常关机未能写入的
&& 未能写入的空记录,也可能是此乱码,请用手工修补
use
=inkey(5)
keyb chr(13)
=inkey()
return
********* 读指定字节并换算为二进制 *********
procedure jread
fstr=fread(fa,l)
mx=0
for i=l to 1 step -1
x=asc(substr(fstr,i,1))
if i>1
mx=(mx+x)*256
else
mx=mx+x
endif
endfor
return(mx)
文章来源:计算机世界。
附加关键字:编程, 源程序, programming, source code, FoxPro/Visual FoxPro, Foxbase, dBase, xbase, FoxPro, VFP, Visual FoxPro, 数据库, database, query。
|