⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adobackup.pas

📁 数据备份与恢复源码,给需要的一个参考,可以直接运行
💻 PAS
📖 第 1 页 / 共 3 页
字号:
function TADOBackup.CopyFloopyFile: Boolean;
var
  i, j: integer;
  SHandle, THandle: Integer;
  FloppySize: integer;
  Buffers: array[0..4095] of Char;
  BlockCount: integer;
  LastBlockSize: integer;
  TempFileName: string;
begin
  SHandle := FileOpen(FOrigPath + FBackUpFileName, fmOpenRead or fmShareDenyNone);
  for i := 0 to Length(FFileHeadList) - 1 do
  begin
    if i <> 0 then
      TempFileName := StringReplace(FBackUpFileName, '.', InttoStr(i + 1) + '.', [rfReplaceAll, rfIgnoreCase])
    else
      TempFileName := FBackupFileName;
    THandle := FileCreate(FWorkPath + TempFileName); // save.dat,save1.dat
    if THandle = -1 then
    begin
      Result := False;
      FileClose(SHandle);
      Exit;
    end;
    FloppySize := FFileHeadList[i].FileSize - Sizeof(TFloppyFileHead); // 获取当前文件包容量
    BlockCount := FloppySize div 4096;
    LastBlockSize := FloppySize mod 4096;
    FileWrite(THandle, FFileHeadList[i], Sizeof(FFileHeadList[i]));

    for j := 1 to BlockCount do
    begin
      FileRead(SHandle, Buffers, 4096);
      FileWrite(THandle, Buffers, 4096);
    end;
    if LastBlockSize <> 0 then
    begin
      FileRead(SHandle, Buffers, LastBlockSize);
      FileWrite(THandle, Buffers, LastBlockSize);
    end;
    FileClose(THandle);
  end;
  FileClose(SHandle);
  Result := True;
end;

procedure TADOBackup.CalFloppyHeadList;
var
  i: integer;
  CompPackSize, LastFloppySize: integer;
  FHandle: Integer;
  FileMaxSize: integer;
  SerialNos: Double;
begin
  FHandle := FileOpen(FOrigPath + FBackUpFileName, fmOpenRead or fmShareDenyNone);
  CompPackSize := Windows.GetFileSize(FHandle, @LastFloppySize); //被分包文件的大小
  FileClose(FHandle);

  FileMaxSize := FPackSize - Sizeof(TFloppyFileHead); //  每个包的最大容量

  i := (CompPackSize + FileMaxSize - 1) div FileMaxSize; // 最多可分成多少包
  SetLength(FFileHeadList, i);
  LastFloppySize := CompPackSize mod FileMaxSize; //最后一个包文件的大小
  SerialNos := Now; // 随即获取序列号

  // 为每一个包填写抬头
  for i := 0 to Length(FFileHeadList) - 2 do
  begin
    with FFileHeadList[i] do
    begin
      ID[0] := 'J';
      ID[1] := 'S';
      ID[2] := 'F';
      ID[3] := 'B';
      SerialNo := SerialNos;
      FloppyCount := Length(FFileHeadList);
      CurFloppyNo := i + 1;
      FileSize := FPackSize;
      FileName := FBackUpFileName;
    end;
  end;
  i := Length(FFileHeadList) - 1;
  with FFileHeadList[i] do
  begin
    ID[0] := 'J';
    ID[1] := 'S';
    ID[2] := 'F';
    ID[3] := 'B';
    SerialNo := SerialNos;
    FloppyCount := Length(FFileHeadList);
    CurFloppyNo := i + 1;
    if LastFloppySize = 0 then
      FileSize := FPackSize
    else
      FileSize := LastFloppySize + Sizeof(TFloppyFileHead);
    FileName := FBackUpFileName;
  end;
end;

function TADOBackup.RestoreData: Boolean;
var
  mADODataSet, mUpdateDataSet: TADODataSet;
  mADOCommand: TADOCommand;
  Bufs, Buftable, BufSql: TStrings;
  i, m: integer;
  TotalCount, NowCount: Integer;
begin
 // Result := False;
  mADODataSet := TADODataSet.Create(nil);
  mADODataSet.Connection := FADOConnection;
  mUpdateDataSet := TADODataSet.Create(nil);
  mUpdateDataSet.Connection := FADOConnection;
  mADOCommand := TADOCommand.Create(nil);
  mADOCommand.Connection := FADOConnection;
  Bufs := TStringList.Create;

  Bufs.LoadFromFile(fTempPath + fn_SQLFile);
  TableMaps.LoadFromFile(fTempPath + fn_TableMap);
  Buftable := GetTableName(Bufs, rtTable);
  BufSql := GetTableName(Bufs, rtSql);
  TotalCount := 0;
  NowCount := 0;
  try
    try
      with mADODataSet do
      begin
        for i := 0 to BUfs.Count - 1 do
        begin
          Close;
          LoadFromFile(fTempPath + TableMaps[i]);
          Open;
          TotalCount := TotalCount + RecordCount;
        end;
      end;
      if not FAutoDel then
      begin
        for i := 0 to FDelSQLStrings.Count - 1 do
        begin
          mADOCommand.CommandText := FDelSQLStrings[i];
          try
            mADOCommand.Execute;
          except
          end;
        end;
      end;
      for i := 0 to Bufs.Count - 1 do
      begin
        if FAutoDel then
        begin
          mADOCommand.CommandText := 'Delete from ' + Buftable[i] + ' ' + BufSql[i];
          try
            mADOCommand.Execute;
          except
          end;
        end;
        mUpdateDataSet.Close;
        mUpdateDataSet.CommandText := 'Select * from ' + Buftable[i];
        mUpdateDataSet.Open;
        with mADODataSet do
        begin
          Close;
          LoadFromFile(fTempPath + TableMaps[i]);
          Open;
          first;
          while not Eof do
          begin
            inc(NowCount);
            try
              mUpdateDataSet.Append;
              for m := 0 to mUpdateDataSet.Fields.Count - 1 do
              begin
                mUpdateDataSet.Fields[m].Value := Fields[m].Value;
              end;
              mUpdateDataSet.Post;
            except
            end;
            if TotalCount = 0 then
              FRadio := 100
            else
              FRadio := (100 * NowCount div Totalcount);
            if Assigned(FRatioChanged) then
              FRatioChanged(Self, fRadio);
            Next;
          end;
        end;
      end;
    except
      raise Exception.Create('数据恢复失败!')
    end;
  finally
    mADODataSet.free;
    mADOCommand.free;
    mUpdateDataSet.free;
    Bufs.Free;
  end;
  Result := True;
end;

function TADOBackup.CopyDevide: Boolean;
var
  i: integer;
  ErrorFlag: Boolean;
  tmpSource, tmpTarget: string;
  ErrorCodes: DWORD;
  Tmps, TempFileName: string;
begin
  Result := True;
  CalFloppyHeadList; // 计算需分割为多少包
  if not CopyFloopyFile then
  begin
    Result := False;
    Exit;
  end;
  if not FisSavetoA then
    Exit;
  ErrorFlag := False;
  for i := 0 to Length(FFileHeadList) - 1 do
  begin
    while True do
    begin
      if Application.MessageBox(PChar('请在 A:\ 驱中放一张空白软盘,然后按确定按钮'),
        PChar('拷贝第 ' + IntToStr(i + 1) + ' 号盘'),
        mb_OKCANCEL + mb_IconInformation) = mrCancel then
      begin
        FErrorType := etCancel;
        Result := False;
        Break;
      end;
      if i <> 0 then
        TempFileName := StringReplace(FBackUpFileName, '.', InttoStr(i + 1) + '.',
          [rfReplaceAll, rfIgnoreCase])
      else
        TempFileName := FBackupFileName;
      tmpSource := FWorkPath + TempFileName; // 从工作路径里提出要拷贝的分割后的文件
      tmpTarget := FSavePath + TempFileName;
      if not CopyFile(PChar(tmpSource), PChar(tmpTarget), False) then
      begin
        ErrorCodes := GetLastError;
        case ErrorCodes of
          ERROR_CANNOT_MAKE: tmpS := '不能在 ' + tmpS + ' 盘创建文件,';
          ERROR_ACCESS_DENIED, ERROR_READ_FAULT: tmpS := '磁盘写错误,磁盘损坏,';
          ERROR_WRITE_PROTECT: tmpS := tmpS + ' 盘被写保护,';
          ERROR_DISK_CHANGE, ERROR_NOT_READY: tmpS := '未插入磁盘,';
          ERROR_DISK_CORRUPT: tmpS := '磁盘被损坏,';
          ERROR_DISK_FULL, ERROR_HANDLE_DISK_FULL: tmpS := '磁盘空间满,';
          ERROR_FLOPPY_UNKNOWN_ERROR: tmpS := '未知错误,';
          ERROR_GEN_FAILURE: tmpS := '磁盘写错误,';
        else
          tmpS := '其他错误,';
        end;
        Messagebeep(0);
        if Application.MessageBox(PChar('拷贝失败: ' + tmpS + '重新拷贝吗?'),
          '错误', MB_OKCANCEL + MB_ICONWARNING) = mrCancel then
        begin
          FErrorType := etCancel;
          ErrorFlag := True;
          Break;
        end;
      end
      else
        Break;
    end;
    if ErrorFlag then
    begin
      Result := False;
      Break;
    end;
  end;
end;

function TADOBackup.StartWrong: Boolean;
begin
  Result := True;
  if not Assigned(FADOConnection) then
  begin
    Application.MessageBox('请先设置ADO连接!', '系统信息', 0 + mb_Iconinformation);
    exit;
  end;
  if not Assigned(FSQLStrings) then
  begin
    Application.MessageBox('请先设置SQL语句!', '系统信息', 0 + mb_Iconinformation);
    exit;
  end;
  if BackupFileName = '' then
  begin
    Application.MessageBox('请先设置备份包名!', '系统信息', 0 + mb_Iconinformation);
    exit;
  end;
  Result := False;
end;

procedure TADOBackup.RebackFiles(mfileName: string); // 恢复文件
var
  mReadFile: file of TFloppyFileHead;
  InfoLen: Integer;
  InfoText: string;
  BackUpstream: TFileStream;
begin
  FSourceFile := mfileName;
  Assignfile(mReadFile, FSourceFile);
  ReSet(mReadFile);
  try
    if not Eof(mReadFile) then
      Read(mReadFile, FFloppyFileHead); // 读取文件头信息
  finally
    CloseFile(mReadFile);
  end;
  if UpperCase(Copy(FSourceFile, 1, 1)) = 'A' then
    FIsSavetoA := True
  else
    FIsSavetoA := False;
  if Directoryexists(FTempPath) then
    RemoveDir(FTempPath);
  ForceDirectories(FTempPath);
  if FFloppyFileHead.ID = 'JSFB' then // 表明是经过处理后的包文件
  begin
    FisDevide := True;
    FBackUpFileName := FFloppyFileHead.FileName;
    if FisSavetoA then
      CopyfromAtoTemp
    else
    begin
      setLength(FFileHeadList, FFloppyFileHead.FloppyCount); // 重设磁盘记录长度
      CopytoTemp(ExtractFilePath(FSourceFile));
    end;
    MergeFloopyFile; // 还原压缩包
    FSourceFile := FOrigPath + FBackUpFileName;
  end
  else // 原始压缩文件
  begin
    FisDevide := False;
    FBackUpFileName := ExtractFileName(FSourceFile);
  end;
  BackUpstream := TFileStream.Create(FSourceFile, fmOpenRead);
  BackUpstream.Position := Length(BackupSign);
  BackUpstream.Read(InfoLen, sizeof(Integer));
  SetLength(InfoText, InfoLen);
  BackUpstream.Read(InfoText[1], InfoLen);
  try
    BackUpFile.RestoreFromStream(BackUpstream, FTempPath); // 直接解压到临时目录
  finally
    BackUpstream.Free;
  end;
  if FisDevide then
    Deletefile(FSourceFile);
end;

function TADOBackup.Restore(SourceFile: string): Boolean;
begin
  Result := False;
  if StartWrong then
    exit;
  RebackFiles(SourceFile);

  if not RestoreData then // 如果数据库更新失败
    exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -