关于目录增量式拷贝的疑问 ( 积分: 100 )

  • 主题发起人 主题发起人 nuaalisa
  • 开始时间 开始时间
N

nuaalisa

Unregistered / Unconfirmed
GUEST, unregistred user!
论坛上的各位朋友,小妹准备做一个目录增量备份的东西,下面的代码是从论坛上搜索来的代码,但小妹水平有限,不知道如何才能将下面的两段代码结合起来使用,从而实现同步两个文件夹的内容,请各位朋友给点提示,谢谢!

nutian (2003-06-15 2:44:00)
好了,终于全部搞定了,实现的功能是:2个文件夹同步,用stringlist装入pfrom中没问题。比较文件速度很快,千多个文件的目录也1秒钟比较完成。
下面给出比较文件的函数和复制文件的函数供大家参考,也算对大富翁论坛的一点点回报:
==============================================================================
//比较文件时间
function DoCopyDir(sDirName:String;sToDirName:String):Boolean;
var
hFindFile,toFindFile:Cardinal;
t,tfile:String;

sCurDir:String[255];
FindFileData,ToFileData:WIN32_FIND_DATA;
begin
//先保存当前目录
sCurDir:=GetCurrentDir;
ChDir(sDirName);
hFindFile:=FindFirstFile('*.*',FindFileData);
if hFindFile<>INVALID_HANDLE_VALUE then //如果找到了文件
begin
if not DirectoryExists(sToDirName) then
ForceDirectories(sToDirName); //目标目录不在就创建
repeat
tfile:=FindFileData.cFileName;

if (tfile='.') or (tfile='..') then
Continue;
if FindFileData.dwFileAttributes=
FILE_ATTRIBUTE_DIRECTORY then //如果文件是子目录
begin
t:=sToDirName+'/'+tfile;
if not DirectoryExists(t) then //子目录不在就创建
ForceDirectories(t);
if sDirName[Length(sDirName)]<>'/' then
DoCopyDir(sDirName+'/'+tfile,t)
else
DoCopyDir(sDirName+tfile,sToDirName+tfile);
end
else //如果是文件,这里是核心
begin
t:=sToDirName+'/'+tFile;
//CopyFile(PChar(tfile),PChar(t),True);
toFindFile:=FindFirstFile(Pchar(t),ToFileData);//寻找目标文件
if toFindFile<>INVALID_HANDLE_VALUE then //如果在就比较时间
begin
if (FindFileData.ftLastWriteTime.dwHighDateTime<>toFileData.ftLastWriteTime.dwHighDateTime)
or (FindFileData.ftLastWriteTime.dwLowDateTime<>toFileData.ftLastWriteTime.dwLowDateTime)
then NameList.Add(GetCurrentDir+'/'+tFile); //如果2个文件时间不同
end
else //如果目标目录没有该文件
NameList.Add(GetCurrentDir+'/'+tFile);
//显示搜寻到的文件的修改时间
//form1.memo1.Lines.Add(inttostr
// (FindFileData.ftLastWriteTime.dwHighDateTime));

//form1.GetFileLastAccessTime(PChar(tfile),PChar(t));
//进度条进一格
form1.ProgressBar1.Position:=form1.ProgressBar1.Position+1;
form1.ProgressBar1.Repaint;
end;
until FindNextFile(hFindFile,FindFileData)=false;
windows.FindClose(hFindFile);
windows.FindClose(ToFindFile);
end
else //一个文件都没找到则
begin
ChDir(sCurDir);
result:=false;
exit;
end;
//回到原来的目录下
ChDir(sCurDir);
result:=true;
end;

==================================================================
function CopyFile(SourceName, TargetName: string): Boolean;
var
F: TShFileOpStruct;
Index: Integer;
Fromdir,Todir,ToFile:string;
begin
for Index := 0 to namelist.Count - 1 do
begin
Fromdir := fromdir+namelist[index]+#0;//从namelist中取出文件名,用#0隔开
ToFile :=TargetName+ copy(namelist[index],length(SourceName)+1,
length(namelist[index])-length(SourceName));//转换为目标路径
Todir :=Todir+ToFile+#0;
end;
F.wnd := Form1.Handle;
F.wFunc := FO_COPY; {操作方式}
F.pFrom := PChar(fromdir+#0);
F.pTo := PChar(Todir+ #0);

F.fFlags:= FOF_NOCONFIRMATION or FOF_MULTIDESTFILES
F.fAnyOperationsAborted:= true;
if ShFileOperation(F)<>0 then showmessage('文件没复制完');
if IOResult<>0 then showmessage('文件没复制完');

end;
==============================================
说明:namelist为函数外部定义的一个全局变量,里面装的是需拷贝的文件列表,定义如下
var namelist:Tstringlist;
 
收藏!
谢谢。
 
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellAPI;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
//文件夹同步函数
procedure SynDirectory(const ASourceDir, ATargetDir: String);
function DoCopyDir(const ASourceDir, ATargetDir: String;
const AList: TStrings): Boolean;
function CopyFileSnd(const ASourceDir, ATargetDir: String;
const AFileList: TStrings): Boolean;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

function TForm1.CopyFileSnd(const ASourceDir, ATargetDir: String;
const AFileList: TStrings): Boolean;
var
F: TShFileOpStruct;
Index,iLen: Integer;
FromList,ToList,sFile,sItem: String;
begin
FromList := '';
ToList := '';
iLen := Length(ASourceDir);
for Index := 0 to AFileList.Count - 1 do begin
sItem := AFileList[Index];
FromList := FromList + sItem + #0; //生成被复制文件列表,用#0隔开
sFile := Copy(sItem,iLen, Length(sItem) - iLen + 1);
ToList := ToList + ATargetDir + sFile + #0; //生成目标文件列表
end;
with F do begin
wnd := Handle;
wFunc := FO_COPY; //操作方式
pFrom := PChar(FromList + #0); //设置被复制文件列表
pTo := PChar(ToList + #0); //设置目标文件列表
fFlags := FOF_NOCONFIRMATION or FOF_MULTIDESTFILES;
fAnyOperationsAborted := True;
end;
Result := (ShFileOperation(F) = 0) and (IOResult = 0);
end;

function TForm1.DoCopyDir(const ASourceDir, ATargetDir: String;
const AList: TStrings): Boolean;
var
hFindFile,toFindFile: Cardinal;
t,tfile: String;
sCurDir: String[255];
FindFileData,ToFileData: WIN32_FIND_DATA;
begin
//先保存当前目录
sCurDir := GetCurrentDir;
ChDir(ASourceDir);
hFindFile := FindFirstFile('*.*',FindFileData);
if hFindFile <> INVALID_HANDLE_VALUE then begin //如果找到了文件
if not DirectoryExists(ATargetDir) then ForceDirectories(ATargetDir); //目标目录不在就创建
repeat
tfile := FindFileData.cFileName;
if (tfile = '.') or (tfile = '..') then Continue;
if FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY then begin //如果文件是子目录
t := ATargetDir + '/' + tfile;
if not DirectoryExists(t) then ForceDirectories(t); //子目录不在就创建
if ASourceDir[Length(ASourceDir)] <> '/' then
DoCopyDir(ASourceDir + '/' + tfile,t,AList)
else
DoCopyDir(ASourceDir + tfile,ATargetDir + tfile,AList);
end
else begin //如果是文件,这里是核心
t := ATargetDir + '/' + tFile;
toFindFile := FindFirstFile(Pchar(t),ToFileData);//寻找目标文件
if toFindFile <> INVALID_HANDLE_VALUE then begin //如果在就比较时间
if (FindFileData.ftLastWriteTime.dwHighDateTime <> toFileData.ftLastWriteTime.dwHighDateTime)
or (FindFileData.ftLastWriteTime.dwLowDateTime <> toFileData.ftLastWriteTime.dwLowDateTime)
then AList.Add(GetCurrentDir + '/' + tFile); //如果2个文件时间不同
end
else begin //如果目标目录没有该文件
AList.Add(GetCurrentDir+'/'+tFile);
end;
end;
until not FindNextFile(hFindFile,FindFileData);
Windows.FindClose(hFindFile);
Windows.FindClose(ToFindFile);
end
else begin //一个文件都没找到则
ChDir(sCurDir);
Result := False;
Exit;
end;
//回到原来的目录下
ChDir(sCurDir);
Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SynDirectory('c:/111/','c:/222/');
end;

//同步函数
procedure TForm1.SynDirectory(const ASourceDir, ATargetDir: String);
var
sList: TStrings;
begin
sList := TStringList.Create;
try
DoCopyDir(ASourceDir,ATargetDir,sList);
if sList.Count > 0 then CopyFileSnd(ASourceDir,ATargetDir,sList);
finally
sList.Free;
end;
end;

end.
 
楼上的大哥,谢谢!
 
楼上的大哥,首先多谢您的热心回复,但是,假如我想将更新后的文件和文件夹放到另外一个新件夹去,这个该咋改?
就是说,将文件夹“111”和文件夹“222”作比较,然后,将所有更新的文件和文件夹放到文件夹“333”去,这个又该如何实现?
小妹由于误操作,未能给您送分,问题解决后,会另外开多一个贴给大哥送分的,谢谢!
 
后退
顶部