以前写过两个类,不过没有用到实际的工作中
感觉里面有很多需要修改的地方
希望对你有帮助
Unit UAutoUpdate_base;
interface
uses
windows,SysUtils,dialogs,Classes,Forms,
IdBaseComponent,IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,IdURI,
Db
;
type
TOnFileWriteEvent = procedure(FileSize:integer;Buf
ointer;BufferSize:integer;BufferCount:integer;CurrentBuffer:integer) of object;
//在文件更新过程中触发的事件
TBeforeFileWriteEvent = procedure(FileSize:integer;BufferSize:integer;BufferCount:integer) of object;
//在文件更新之前触发的事件
TAfterFileWriteEvent = procedure(FileSize:integer;BufferSize:integer;BufferCount:integer) of object;
//在文件更新之后触发的事件
FileBuffer = array [0..4095] of byte;
//文件更新时的缓存
TUpDateFile = class (Tobject)
//文件更新类型
private
FTargetFileName:string;
FSourceFileName:string;
FStop:boolean;
FBeforeUpdateFile:TBeforeFileWriteEvent;
FOnUpDateFile:TOnFileWriteEvent;
FAfterUpdateFile:TAfterFileWriteEvent;
procedure FSetTargetFileName(const Value:string);
procedure FSetSourceFileName(const Value:string);
public
function Execute:Boolean;
//执行文件更新操作。返回值执行结果
function UpdateFile(TargetFile:string;SourceFile:string):Boolean;
//根据文件名实现文件的更新
procedure StopUpdate;
//停止文件更新
published
//目标文件名
property TargetFileName:string Read FTargetFileName write FSetTargetFileName;
//源文件名
Property SourceFileName:string Read FSourceFileName write FSetSourceFileName;
Property OnUpDateFile:TOnFileWriteEvent Read FOnUpDateFile write FOnUpDateFile;
//文件更新时触发的事件
Property BeforeUpDateFile:TBeforeFileWriteEvent Read FBeforeUpDateFile Write FBeforeUpDateFile;
//文件更新前触发的事件
Property AfterUpDateFile:TAfterFileWriteEvent Read FAfterUpdateFile Write FAfterUpDateFile;
//文件更新后触发的事件
end;
THttpDownFile = class(Tobject)
//通过HTTP协议下载文件的类型
private
FUrl:WideString;
//文件的网络地址
FTargetFileName:String;
//目标文件的位置
FBeforeDownLoadFile:TBeforeFileWriteEvent;
//文件下载前执行的事件
FOnDownLoadFile:TOnFileWriteEvent;
//文件下载过程中执行的事件
FAfterDownLoadFile:TAfterFileWriteEvent;
//文件下载后执行的事件
FStop:bool;
public
function Execute:Boolean;
//执行文件更新操作
function DownLoadFile(Url:Widestring;TargetFile:String):Boolean;
//根据文件网络位置和目标文件的名称来更新文件
procedure StopDownload;
//停止文件更新操作
published
Property Url:WideString Read FUrl Write FUrl;
//文件地址
property TargetFileName:String Read FTargetFileName Write FTargetFileName;
//目标文件名称
property BeforeDownLoadFile:TBeforeFileWriteEvent Read FBeforeDownLoadFile Write FBeforeDownLoadFile;
property OnDownLoadFile:TOnFileWriteEvent Read FOnDownLoadFile write FOnDownLoadFile;
property AfterDownLoadFile:TAfterFileWriteEvent Read FAfterDownLoadFile Write FAfterDownLoadFile;
end;
TDBDownFile = class(Tobject)
//从数据库取得文件的模块
private
FDataSet:TDataSet;
FFileFieldName:String;
//数据库中保存文件的字段
FTargetFileName:String;
FStop:Boolean;
FBeforeDownLoadFile:TBeforeFileWriteEvent;
//文件下载前执行的事件
FOnDownLoadFile:TOnFileWriteEvent;
//文件下载过程中执行的事件
FAfterDownLoadFile:TAfterFileWriteEvent;
//文件下载后执行的事件
public
function Execute:boolean;
//执行文件下载的操作
function DownLoadFile(FileFieldName:String;TargetFile:string):boolean;
procedure StopDownload;
published
property DataSet:TDataSet Read FDataSet Write FDataset;
Property FileFieldName:String Read FFileFieldName Write FFileFieldName;
//保存文件的数据库字段
Property TargetFile:string Read FTargetFileName Write FTargetFileName;
//要保存文件的位置
Property BeforeDownloadFile:TBeforeFileWriteEvent Read FBeforeDownloadFile Write FBeforeDownloadFile;
//下载前的事件
Property OnDownloadFile:TOnFileWriteEvent Read FOnDownloadFile Write FOnDownloadFile;
//下载中的事件
Property AfterDownloadFile:TAfterFileWriteEvent Read FAfterDownloadFile Write FAfterDownloadFile;
//下载后的事件
end;
implementation
{ TUpDateFile }
function TUpDateFile.Execute: Boolean;
begin
result:=UpdateFile(FTargetFileName,FSourceFileName);
end;
procedure TUpDateFile.FSetSourceFileName(const Value:string);
begin
FSourceFileName:=Value;
end;
procedure TUpDateFile.FSetTargetFileName(const Value: string);
begin
FTargetFileName:=Value;
end;
procedure TUpDateFile.StopUpdate;
begin
FStop:=True;
end;
//文件更新函数
function TUpDateFile.UpdateFile(TargetFile, SourceFile: string): Boolean;
var
SS:TFileStream;
TS:TFileStream;
Buf:FileBuffer;
BufCnt:integer;
BufSize:integer;
FileSize:integer;
i:integer;
begin
Result:=False;
If FileEXists(FSourceFileName) then
begin
SS:=TFileStream.Create(FSourceFileName,fmOpenRead);
TS:=TFileStream.Create(FTargetFileName,fmCreate);
//创建源文件流和目标文件流
SS.Position:=0;
TS.Position:=0;
FileSize:=SS.Size;
BufSize:=Sizeof(buf);
Bufcnt:=Filesize div BufSize;
If (Filesize mod BufSize)<>0 then
BufCnt:=BufCnt+1;
if Assigned(FBeforeUpdateFile) then
FBeforeUpdateFile(FIleSize,BufSize,BufCnt);
zeromemory(@Buf,sizeof(Buf));
FStop:=False;
//写文件
for i:=1 to FileSize div BufSize do
begin
SS.Read(Buf,BufSize);
If Assigned(FOnUpDateFile) then
FOnUpDateFile(FileSize,@buf,Bufsize,Bufcnt,i);
TS.Write(Buf,BufSize);
If Fstop then break;
Application.ProcessMessages;
end;
if ((SS.Size mod BufSize)<>0) and (not Fstop) then
begin
SS.Read(Buf,(SS.Size mod BufSize));
If Assigned(FOnUpDateFile) then
FOnUpDateFile(FileSize,@buf,bufsize,Bufcnt,Bufcnt);
TS.Write(Buf,(SS.Size mod BufSize));
end;
if assigned(FAfterUpDateFile) then
FAfterUpdateFile(FileSize,BufSize,Bufcnt);
Result:=True;
SS.Destroy;
TS.Destroy;
end;
end;
{ THttpDownFile }
function THttpDownFile.DownLoadFile(Url: Widestring;
TargetFile: String): Boolean;
var
HttpC:TIdHttp; //HTTP连接
Http_Header:TStrings; //请求文件的HTTP头
Filesize:Integer; //文件大小
TS:TFileStream; //目标文件流
Buf:FileBuffer;
BufSize:Integer;
BufCnt:integer;
i:integer;
begin
Result:=False;
FStop:=false;
HttpC:=TIdHttp.Create(nil);
Http_Header:=TStringList.Create;
TS:=TFileStream.Create(TargetFile,fmCreate);
//初始化
Try
HttpC.Head(Url); //请求网络文件的头信息
FileSize:=Httpc.Response.ContentLength;
BufSize:=SizeOf(Buf);
BufCnt:=FileSize div BufSize;
if (FileSize mod BufSize) <>0 then
BufCnt:=BufCnt+1;
//计算缓存的个数
if Assigned(FBeforeDownLoadFile) then
FBeforeDownLoadFile(FileSize,BufSize,BufCnt);
//执行文件更新前的事件
Http_Header.Add('GET '+HttpC.URL.Path+HttpC.URL.Document+' HTTP/1.1');
Http_Header.Add('Accept: */*');
Http_Header.Add('RANGE: bytes=1-');
//Http_Header.Add('User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)');
Http_Header.Add('Host: '+HttpC.URL.Host);
//生成请求文件的头信息
if not HttpC.Connected then HttpC.Connect;
HttpC.WriteHeader(Http_Header);
//发送请求文件的头信息
while HttpC.ReadLn<>'' do;
Zeromemory(@Buf,sizeof(buf));
for i:=1 to (FileSize div BufSize) do
begin
HttpC.ReadBuffer(Buf,Sizeof(Buf));
if Assigned(FOnDownLoadFile) then
FOnDownLoadFile(Filesize,@Buf,Bufsize,Bufcnt,i);
if Fstop then Break;
TS.WriteBuffer(Buf,Sizeof(Buf));
Application.ProcessMessages;
end;
if ((FileSize mod BufSize) <>0) and (not Fstop) then
begin
HttpC.ReadBuffer(Buf,(FileSize mod BufSize));
if Assigned(FOnDownLoadFile) then
FOnDownLoadFile(Filesize,@Buf,(FileSize mod BufSize),Bufcnt,Bufcnt);
TS.WriteBuffer(Buf,(FileSize mod BufSize));
end;
//读取文件到本地
if Assigned(FAfterDownLoadFile) then
FAfterDownLoadFile(Filesize,BufSize,BufCnt);
HttpC.Disconnect;
Result:=True;
except
//raise Exception.Create('Not Found');
end;
// uri.Destroy;
TS.Destroy;
Http_Header.Destroy;
HttpC.Destroy;
end;
function THttpDownFile.Execute: Boolean;
begin
Result:=DownLoadFile(FUrl,FTargetFileName);
end;
procedure THttpDownFile.StopDownload;
begin
FStop:=true;
end;
{ TDBDownFile }
function TDBDownFile.DownLoadFile(FileFieldName: String;
TargetFile:string): boolean;
var
Filesize:Integer; //文件大小
TS:TFileStream; //目标文件流
Buf:FileBuffer;
BufSize:Integer;
BufCnt:integer;
i:integer;
BlobStream: TStream;
// FileField:TBlobField;
begin
result:=False;
FStop:=False;
If Assigned(FDataset) then
begin
{
TS.Destroy;
BlobStream.Destroy;
if Assigned(FAfterDownLoadFile) then
FAfterDownLoadFile(FileSize,BufSize,BufCnt);
Result:=true;}
if FDataSet.Active then
begin
FDataSet.First;
TS:=TFileStream.Create(TargetFile,fmCreate);
While not FDataSet.Eof do
begin
BlobStream := FDataSet.CreateBlobStream(FDataset.FieldByName(FFileFieldName), bmRead);
Filesize:=BlobStream.Size;
BufSize:=sizeof(Buf);
BufCnt:=(FileSize div BufSize);
if (FileSize mod BufSize)<>0 then
BufCnt:=BufCnt+1;
if Assigned(FBeforeDownLoadFile) then
FBeforeDownLoadFile(FileSize,BufSize,BufCnt);
ZeroMemory(@Buf,BufSize);
For i:=1 to (FileSize div BufSize) do
begin
BlobStream.Read(Buf,BufSize);
if Assigned(FOnDownLoadFile) then
FOnDownLoadFile(Filesize,@Buf,BufSize,BufCnt,i);
if Fstop then Break;
Ts.Write(Buf,BufSize);
Application.ProcessMessages;
end;
if ((FileSize mod BufSize)<>0) and (not FStop) then
begin
BlobStream.Read(Buf,(FileSize mod BufSize));
if Assigned(FOnDownLoadFile) then
FOnDownLoadFile(Filesize,@Buf,BufSize,BufCnt,BufCnt);
Ts.Write(Buf,(FileSize mod BufSize));
Application.ProcessMessages;
end;
if Assigned(FAfterDownLoadFile) then
FAfterDownLoadFile(FileSize,BufSize,BufCnt);
FDataSet.Next;
end;
end;
end;
end;
function TDBDownFile.Execute: boolean;
begin
result:=DownLoadFile(FFileFieldName,FTargetFileName);
end;
procedure TDBDownFile.StopDownload;
begin
FStop:=true;
end;
end.