多线程复制文件的源码
unit U_CopyThread;
interface
uses
Windows, Messages, SysUtils, Classes;
const
//自军定义消息MSG_COPY:传送文件拷贝的进度信息;
//wParam: 后台线程的线程ID;
//lParam: 已拷贝的字节数;
MSG_COPY_COUNT = WM_USER + 100;
MSG_COPY_SUCESS = WM_USER + 101;
MSG_COPY_FAILED = WM_USER + 102;
type
//将指定文件名的源文件拷贝到指定文件名的目标文件的后台线程;
TCopyThread = class(TThread)
private
FSource: string;
//源文件名;
FTarget: string;
//目的文件名;
FMainHandle: THandle;
//调用本线程的主线程句柄;
// FFileSize: Integer;
//源文件大小;
FCopyCount: Integer;
//已拷贝的字节数;
FBufferSize: Integer;
//拷贝用缓冲区大小;
FDelayTime: Integer;
//线程休息等待时间;
procedure CopyStream(Src, Dest: TStream);
procedure SetBufferSize(const Value: Integer);
procedure SetDelayTime(const Value: Integer);
protected
procedure Execute;
override;
public
//如不需要后台线程反馈消息,调用时只用前两个参数即可;
constructor Create(ASrcFile, ADestFile: string;
AHandle: THandle = 0);
//BufferSize属性:设置复制时的缓冲区大小;
property BufferSize: Integer read FBufferSize write SetBufferSize;
property DelayTime: Integer read FDelayTime write SetDelayTime;
// property CopyCount: Integer read FCopyCount;
// property FileSize: Integer read FFileSize;
property Terminated;
end;
//判断文件是否存在并返回其大小;
function GetFileSize(AFile: string): Integer;
implementation
function GetFileSize(AFile: string): Integer;
begin
Result := 0;
if not FileExists(AFile) then
Exit;
with TFileStream.Create(AFile, fmOpenRead)do
try
Result := Size;
finally
Free;
end;
end;
{ TCopyThread }
constructor TCopyThread.Create(ASrcFile, ADestFile: string;
AHandle: THandle);
begin
inherited Create(True);
FSource := ASrcFile;
FTarget := ADestFile;
FMainHandle := AHandle;
Priority := tpIdle;
FBufferSize := $F000;
FreeOnTerminate := True;
end;
procedure TCopyThread.Execute;
var
Src, Dest: TFileStream;
begin
// if not FileExists(FSource) then
Exit;
Src := TFileStream.Create(FSource, fmOpenRead);
try
// FFileSize := Src.Size;
if FileExists(FTarget) then
DeleteFile(FTarget);
Dest := TFileStream.Create(FTarget, fmCreate);
try
CopyStream(Src, Dest);
finally
Dest.Free;
end;
finally
Src.Free;
end;
end;
procedure TCopyThread.CopyStream(Src, Dest: TStream);
var
Count, BufSize, N: Integer;
Buffer: Pointer;
//PChar;
begin
Count := Src.Size;
Src.Position := 0;
Dest.Position := 0;
if Count > FBufferSize then
BufSize := FBufferSize else
BufSize := Count;
GetMem(Buffer, BufSize);
try
while not Terminated and (Count <> 0)do
begin
if Count > BufSize then
N := BufSize else
N := Count;
Src.ReadBuffer(Buffer^, N);
Dest.WriteBuffer(Buffer^, N);
Dec(Count, N);
Inc(FCopyCount, N);
if FMainHandle <> 0 then
//反馈进度;
PostMessage(FMainHandle, MSG_COPY_COUNT, ThreadID, FCopyCount);
//让线程等待(由FDelayTime)指定的时间片;
if FDelayTime > 0 then
Sleep(FDelayTime);
end;
finally
FreeMem(Buffer, BufSize);
if FMainHandle <> 0 then
//反馈复制是否成功;
begin
if FCopyCount = Src.Size then
PostMessage(FMainHandle, MSG_COPY_SUCESS, ThreadID, FCopyCount)
else
PostMessage(FMainHandle, MSG_COPY_FAILED, ThreadID, FCopyCount);
end;
end;
end;
procedure TCopyThread.SetBufferSize(const Value: Integer);
begin
if (Value > 0) and (FBufferSize <> Value) then
FBufferSize := Value;
end;
procedure TCopyThread.SetDelayTime(const Value: Integer);
begin
if (Value > 0) and (FDelayTime <> Value) then
FDelayTime := Value;
end;
end.