通过编程修复已损坏的表中的问题

来源:互联网 发布:cp linux 编辑:程序博客网 时间:2024/05/01 23:13
 A:如何修复被破坏的VFP表(*.dbf)

----目前在我国,有相当一部分正在运行应用程序是用VFP 编写的,由于突然断电、程序非法关闭等原因,经常会导致VFP数据表.DBF文件被破坏,如果数据表被破坏了,用VFP打开数据表.DBF时,会出现"notatable/dbf"错误提示,导致无法用VFP打开。
----首先介绍一下VFP数据表.DBF的文件结构:
----VFP数据表*.DBF的文件结构由头记录和数据记录组成,头记录定义该DBF的结构并包含与该表相关的其它信息。头记录由文件位置0字节开始。
----数据表头部几个关键字节含义如下:(注:表文件中存储整数时低位字节在前)
----字节偏移说明
----0 表文件的版本类型
----1-3 最近更新的日期(YYMMDD)
----4-7 表文件中记录的个数
----8-9 第一条记录的起始位置
----10-11 一条记录的长度(包括删除标记)
----其它字节的具体描述不在此赘述,可以参考有关部门书籍或者程序开头注释部分。
----在实际工作中发现,许多情况下数据表错误都是由于记录个数比实际记录个数大1个,以至于数据表无法用打开。
----主要通过以下两种办法来对数据表进行修复。

一、用Pctools、urledit、NU的Diskedit等工具软件进行恢复:

----运行Pctools,选中无法打开的数据表,按E文件进入编辑功能,按F1切换显示模式。
----按F3进行编辑,将开始的第5个字节值减1,按F5存储,然后退出Pctools,启动VFP, 发现被破坏的数据表可以打开使用了。
----由于许多操作者并不一定熟悉如何使用Pctools,因此我建议大家可以用比较熟悉的Excel程序根据下面的步骤来进行数据表的恢复。
----用urledit编辑,将开始的第5个字节值改成另一个正常表文件相同的值,存储后退出

二、用Excel进行恢复。

----启动Excel,选择"打开"按钮,出现打开对话框,在打开文件类型中选择dBase文件(*.DBF)文件类型,再选中被破坏的数据表打开,这时不要做更改,只选择"保存"按钮,会出现"另存为"对话框,仍选择以原来文件名保存,会提示"文件已经存在,是否替换已有文件?",选择"是"。
----然后选择"文件"菜单上的"关闭",会出现提示"数据表文件不是Excel格式,要保留修改吗?
----要保存为Excel格式,单击'是',然后在'保存类型'下拉列表框选'Excel工作簿';
----要用现有格式保存并替换原来的文件,单击'是',然后单击'保存';
----要在关闭文件时维持现有格式并不作保存,单击'否'。"
----由于我们并没有对数据表的记录进行改动,只是为了恢复数据表,所以选择最后一项"在关闭文件时维持现有格式并不作保存",因此单击"否",退出Excel。
----启动VFP,再次打开数据表文件,发现数据表文件已可以被打开了,但是观察数据表的结构,会发现数据表结构中的索引不见了,不过数据表的索引文件还存在。我们只需要给数据表Add索引,并选择原来的索引文件Open即可。
----添加索引文件后退出数据表结构设置,并对数据表重新索引一下,就可以继续使用原 来被破坏的数据表了。

三、如果是VFP6的DBF,那么用VFP8打开试一试。如果是VFP8的DBF,那么用VFP6打开试一试


四、如果你的软件提示“不是DATABASE 数据库”等意思说明你的数据库已经受损,需要进行修理。本人在实践中,摸索出几种可行的办法,以供大家参考,如有不正确之处或者其他更好的方法,希望不吝赐教:

    方法1、如果你有Delphi的Database DeskTop,修复DBF文件是一件非常容易的事,只要打开损坏的数据库(用Database DeskTop是可以打开损坏的DBF数据表的),修正损坏的记录,一般是最后几条记录,不能修正的损坏记录也只有删除了,然后存盘即可,Database DeskTop的存盘功能会将正确的数据存入数据表中,当然数据表是要重新索引的。

    方法2、使用Excel或Access都可以修复DBF文件,不过要一些信息。首先用EXCEL或ACCESS导出正确的数据,将其另存为一个同版本的DBF数据表,再通过修改DBF数据表的字段结构,来修正属性,最后重建索引,这种方法比较烦琐,需要的信息较多,在手头没有其他工具时,才可用此方法修复。
    Excel可以直接打开DBF格式的文件,何不一试?启动Excel 2000,打开此DBF文件,竟然没有任何出错信息,内容完好如初,立即以dBase 4数据库格式存盘,再运行Foxpro,这时,笔者已能用USE命令直接打开数据库,不过在运行应用程序时出现“数据库未索引”错误信息,估计用Excel存盘后导致索引文件丢失所致,遂重新索引一遍再试,程序运行正常。
  总结:DBF文件结构比较简单,数据库记录一般都以文本格式存放,只是前面加了反映库结构的文件头,因此损坏后也易修复,上述即为一例,我们需要注意两点:一是存盘格式应为dBase 4的DBF格式,二是原数据库的索引文件必须重建。

    方法3、目前网络上也有许多自称可以自动修理DBF数据表及其索引的工具,可以试用自动修理工具进行修复。
    Advanced DBF Repair (ACR)是一款强大的修复受损 DBF 文件的工具,它可以扫描 DBF 文件并尽可能恢复其中的数据 ,将由数据损坏带来的损失减至最低.下载地址http://www.fixdown.com/soft/24185.asp

------------------------------------------------------------------------------------------------------------------------------

~~~~~B:恢复无法打开的数据库文件(*.dbc)

-----方法一:
执行
VALIDATE DATABASE RECOVER
命令看看有什么效果,语法如下:
*---------------------------------
保证当前数据库中表和索引位置的正确性。

Validate Database [RECOVER] [NOCONSOLE]
  [TO PRINTER [PROMPT] | TO FILE FileName]
参数
RECOVER
显示一个对话框,该对话框允许您定位表和索引,这些表和索引不在被检查的数据库中。必须在命令窗口中发出 Validate Database RECOVER 命令,在程序中发布该命令会产生错误信息。
NOCONSOLE
不向 Visual FoxPro 主窗口或活动的用户自定义窗口输出错误信息。
TO PRINTER [PROMPT]
将 VALIDATE DATABASE 命令的错误信息定向输出到打印机。
PROMPT 在打印前显示“打印”对话框,该关键字应紧跟在 TO PRINTER 之后。

TO FILE FileName
将错误信息定向输出到由 FileName 参数指定的文件,如果该文件已经存在,并且 SET SAFETY 值为 ON,系统会询问是否要覆盖该文件。
备注
VALIDATE DATABASE 命令确保数据库包含的表和索引处于正确位置,确保数据库中的表包含正确的字段,以及确定数据库中索引标识是否存在。

VALIDATE DATABASE 命令在当前数据库上操作。在发布 OPEN DATABASE 命令打开此数据库时,必须包含 EXCLUSIVE 关键字,以独占方式打开。

示例
下面的示例打开 testdata 数据库并使用 VALIDATE DATABASE 命令,以确定表和索引的位置在数据库中是正确的。

CLOSE DATABASES
SET PATH TO (HOME(2) + 'Data\') && 设置数据库路径
OPEN DATABASE testdata EXCLUSIVE && 打开 testdata 数据库

Validate Database

*------------------------------
如果还是不行,
就只好:
1、删除dbc文件
2、去掉所有dbf文件对数据库的引用
3、再新建一个dbc
4、然后加入所有dbf文件

------方法二:
 
    在使用VFP数据库软件时,有时会发生数据库文件无法打开的错误,如:(1) not a database file(不是数据库文件) 。(2) memo file is missing/invalid(备注文件丢失/无效)等。若无法打开的数据库文件不能恢复,将给用户带来损失。那么如何恢复无法打开的数据库文件呢?首先须清楚数据库文件的结构。VFP中的数据库文件由文件描述部分和文件的数据内容两部分组成。文件的描述部分在文件前部,描述部分结束后是文件中存储的数据记录。文件描述又分成两部分:文件的整体结构的描述和每个字段的描述。整体结构描述由文件的第一个字节开始,共需32个字节。其中:
  第1字节:备注文件标志位;
  第2~4字节:文件的最后修改日期(年,月,日);
  第5~8字节:文件记录数,低位在前高位在后;
  第9~10字节:数据计录内容存储的开始位置,即字段描述结束后的下一个字节位置,低位在前高位在后;
  第11~12字节:记录长度(全部字段长之和),低位在前高位在后;
  第29字节:组合索引文件存在标记。
  从第33个字节开始,每32个字节描述一个字段。
  第1字节为“f5”表示数据库文件应有备注文件,若无备注文件欲打开该数据库文件就会出现本文开头的错误信息(2),此时只须将“f5”改成“03”即可(用pctool),“03”表示数据库文件无备注文件。
  第29字节为“01”,表示数据库文件打开的同时打开组合索引文件。若无组合索引文件,也会出现错误提示信息,将“01”改成“00”即可,“00”表示数据库文件无组合索引文件。
  欲打开数据库文件,屏幕报告“not a database file”(不是数据库文件)错误,是由于第5~8字节表示的文件记录数大于数据库文件实际记录数(若小于等于数据库文件实际记录数则不会报告错误),此时恢复该数据库文件只要获得文件的实际记录数,用手工方法修改文件的第5~8字节。数据库文件实际记录数可以通过下面的公式计算:
  记录数=(文件长度-文件描述部分长度-文件结束标志长度)/记录长度式中,文件长度可通过“dir”命令获得;
  文件描述部分长度=(第10字节)10 *256+(第9字节)10 ;
  文件结束标志长度=1;
  记录长度=(第12字节)10 *256+(第11字节)10;
  若是数据库文件上述公式一定能整除,由公式计算出的记录数再换算成16进制填入文件的第5~8字节,注意低位在前高位在后。
  根据上述过程笔者用c语言编写了恢复该数据库文件的程序modi.cpp(该程序在bc31 for dos下编译通过):
  #include 
  #include 
  #include 
  int main(int argc,char *argv[])
  {
   file *fp;
   unsigned int c[4],i;
   long int total,records;
   if(argc!=2){
   printf("no file name!\n");
    exit(1);
  }
   if( (fp=fopen(argv[1],"r+b"))==null){
   printf("not find %s!\n",argv[1]);
   exit(1);
   }
   total=filelength(fileno(fp));//获得文件长度
   rewind(fp);
   i=fgetc(fp); //读取第1个字节的值
   if (i!=0xf3&&i!=0x03){
   fseek(fp,-1l,1);
   fputc(0x03,fp); //第1个字节的值若不为“f3”或“03”
   } //则强迫为“03”
   rewind(fp);
   fseek(fp,8l,1); //指针指向第9字节
   c[0]=fgetc(fp); //读取第9~12字节的值
   c[1]=fgetc(fp);
   c[2]=fgetc(fp);
   c[3]=fgetc(fp);
   records=(total-c[1]*256+c[0]-1)/(c[2]+c[3]*256);//计算记录数
   c[0]=records%256; //c[0]~c[3]计算第5~8字节的值
   c[1]=(records-c[3]*256*256*256-c[2]*256*256)/256;
   c[2]=(records-c[3]*256*256*256)/65536;
   c[3]=records/256/256/256;
   fseek(fp,-8l,1); //指针指向第5字节
   fputc(c[0],fp); //将c[0]~c[3]写入第5~8字节
   fputc(c[1],fp);
   fputc(c[2],fp);
   fputc(c[3],fp);
   printf("modify the database file successfully!\n");
   fclose(fp);
   return 1;

--------方法三:
  将所有的dbf,cdx,dbc文件都删除了。然后用它们的备分文件件,bak,dcx,bdc分别改名,然后,在项目里打开数据库,将里面的所有表移除,删除数据库,再新新建数据库,再将表加入。

原创粉丝点击