?? adobackup.pas
字號:
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 + -