|
Post by otomazeli on Nov 26, 2007 10:47:59 GMT -5
Hello Kevin, I'm actually working for a company that uses your zip component; it works really great, well done! I'm designing a data transfer using ftp protocol and I'm using TVCLzip/unzip to do it. My question is ::)I have many clients connecting to my server and sending zipped files and I need receive all files at the same time and unzip them in the right place so I need to start many instances of TVCLUnzip at the same time my question TVCLUnzip can handle this by itself or I need to implement something using thread? I'm not very expert with threads can you help me with that? Do you have any example? Thanks in advance for any information ;D
|
|
|
Post by Kevin on Nov 26, 2007 14:16:14 GMT -5
Hi!
VCLZip won't handle that by itself. But it will work if you create separate instances of VCLZip. So yes, you will probably want to use threads.
My experience with threads is mostly in Java, but I believe they should be very similar so I will see if I can put together a simple example.
Kevin
|
|
|
Post by Kevin on Nov 26, 2007 21:08:04 GMT -5
This has not been tested or even compiled so it likely has errors, this is only meant to be a possible example...
Here is an example of the thread class. ==============
interface
uses TVCLUnZip;
type TVCLZipThrd = class(TThread) private unzipper: TVCLUnZip; FDestination: String; FZipFileName: String; protected procedure Execute; override; public property Destination: String write FDestination; property ZipFileName: String write FZipFileName; end;
implementation
procedure TVCLZipThrd.Execute; begin unzipper := TVCLUnzip.Create(nil); unzipper.ZipName := FZipFileName; unzipper.DestDir := FDesination; unzipper.RecreateDirs := true; unzipper.Unzip; end;
end.
Here is an example of calling the thread. =============
procedure MainObject.SpawnUnZip(Archive: String; Dest: String);
var NewThread: TPrimeThrd;
begin NewThread := TVCLZipThrd.Create(True); NewThread.FreeOnTerminate := True; try NewThread.ZipFileName := Archive; NewThread.Destination := Dest; NewThread.Resume; except begin NewThread.Free; // Log errors here end; end; end;
|
|
|
Post by otomazeli on Nov 27, 2007 8:49:44 GMT -5
Thank you very much for the example, I'm going to test right now and I let you know how it work out.
Thank you very much
Regards,
|
|
|
Post by Kevin on Nov 27, 2007 9:47:34 GMT -5
Let us know how it goes!!! :-)
|
|
|
Post by otomazeli on Nov 28, 2007 16:27:03 GMT -5
Hi,
Here my first class using with Indy 10
unit ThreadZip;
interface
uses Classes, Windows, VCLUnZip, VCLZip, IdCommandHandlers, IdContext, SysUtils, ComCtrls;
type TDisplayStatus = procedure(Msg: string; Senderror: Boolean; ErrorType, ErrorNumb: Integer; const AClient: TIdContext = nil; Store: string = ''; AImageIndex: Integer = 12) of object; TUpdateListview= procedure(Sender: TObject; Client: TIdContext; oListView: TListView; AIp, AClientStore, AMessage: string; AMsgImage, APosition: Integer; const AMax: Integer = 0) of object;
TThreadZip = class(TThread) private { Private declarations } FPassword:String; FHost:String; FResult:Boolean; FListOfFiles:TStringList; FFileName:String; FDelete:Boolean; FSender:TIdCommand; FZip:TVCLZip; FListView:TListView; FOnFilePercentDone:TFilePercentDone; FOnTotalPercentDone:TTotalPercentDone; FOnInCompleteZip:TInCompleteZip; FOnDisplayStatus:TDisplayStatus; FOnUpdateListView:TUpdateListview; protected procedure Execute; override; public constructor Create(AListOfFiles: TStringList; ATargetZIPFileName: string; ADelete: Boolean; const ASender: TIdCommand = nil; AHost:String=''; APassword:String=''); published property ListView: TListView READ FListView WRITE FListView; property Result: Boolean READ FResult WRITE FResult; property OnFilePercentDone: TFilePercentDone READ FOnFilePercentDone WRITE FOnFilePercentDone; property OnTotalPercentDone: TTotalPercentDone READ FOnTotalPercentDone WRITE FOnTotalPercentDone; property OnInCompleteZip: TInCompleteZip READ FOnInCompleteZip WRITE FOnInCompleteZip; property OnDisplayStatus: TDisplayStatus READ FOnDisplayStatus WRITE FOnDisplayStatus; property OnUpdateListView: TUpdateListview READ FOnUpdateListView WRITE FOnUpdateListView; end;
resourcestring strCheckingZipFiles = 'Beginning integrity test for %s files for %s'; strZipping = 'Zipping Files'; strFileZipOK = 'Zip file integrity is OK.'; strFileZipCorrupted = 'Zip file is corrupted.'; strFileCheckOK = 'File Check OK'; strFileCheckFailed = 'File Check FAILED.'; strDeletingFile = 'Deleting File '; strErrorDeletingFile = 'Error deleting file: %s ';
implementation
{ Important: Methods and properties of objects in VCL can only be used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TThreadZip.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; }
function IFF(ACondition: Variant; ATrue: TIdCommand): TIdContext; begin if ACondition then result := ATrue.Context else result := nil; end;
{ TThreadZip }
constructor TThreadZip.Create(AListOfFiles: TStringList; ATargetZIPFileName: string; ADelete: Boolean; const ASender: TIdCommand; AHost:String; APassword:String); begin FResult := False; FListOfFiles:= TStringList.Create; FListOfFiles.Assign(AListOfFiles);
FFileName := ATargetZIPFileName;
FDelete:=ADelete;
FSender := ASender; FPassword := APassword; FHost := AHost;
FreeOnTerminate := True; inherited Create(False); end;
procedure TThreadZip.Execute; var i:integer; begin { Place thread code here } FResult := False; with FZip.Create(nil) do begin OnFilePercentDone := FOnFilePercentDone; OnTotalPercentDone := FOnTotalPercentDone; OnInCompleteZip := FOnInCompleteZip; if Assigned(FSender) then VCLComObject := FSender; ResetArchiveBitOnZip := False; ZipName := FFileName; FilesList.Assign(FListOfFiles); Recurse := False; //* Recurse directories */ StorePaths := False; //* Keep path information */ PackLevel := 9; //* Highest level of compression */ if FPassword <> EmptyStr then Password := FPassword; ///Set security password
Zip; //* Return value of Zip is the actual number of files zipped */
sleep(500); ///timer to finish and close zip file
FOnDisplayStatus(Format(strCheckingZipFiles, [IntToStr(Count), ZipName]), false, 0, 0, IFF(Assigned(FSender), FSender));
if Assigned(FListView) then begin if Assigned(FSender) then FOnUpdateListView(self, FSender.Context, FListView, EmptyStr, EmptyStr, strZipping, 7, 1, Count - 1) else FOnUpdateListView(self, nil, FListView, FHost, EmptyStr, strZipping, 7, 1, Count - 1); end;
for i := 0 to Count - 1 do begin if Assigned(FListView) then begin if Assigned(FSender) then FOnUpdateListView(Self, FSender.Context, FListView, EmptyStr, EmptyStr, strZipping, 7, i, 0) else FOnUpdateListView(Self, nil, FListView, FHost, EmptyStr, strZipping, 7, i, 0); end;
if FileIsOK[i] then FResult := true else begin FResult := false; break; end; end; end; //with
if FResult then begin if Assigned(FListView) then begin if Assigned(FSender) then FOnUpdateListView(Self, FSender.Context, FListView, EmptyStr, EmptyStr, strFileZipOK, 6, i, 0) else FOnUpdateListView(Self, nil, FListView, FHost, EmptyStr, strFileZipOK, 6, i, 0); end;
FOnDisplayStatus(strFileCheckOK, false, 0, 0, IFF(Assigned(FSender), FSender)); end else begin if Assigned(FListView) then begin if Assigned(FSender) then FOnUpdateListView(Self, FSender.Context, FListView, EmptyStr, EmptyStr, strFileZipCorrupted, 9, i, 0) else FOnUpdateListView(Self, nil, FListView, FHost, EmptyStr, strFileZipCorrupted, 9, i, 0); end; FOnDisplayStatus(strFileCheckFailed, false, 0, 0, IFF(Assigned(FSender), FSender)); FOnDisplayStatus(strDeletingFile + FFileName, false, 0, 0, IFF(Assigned(FSender), FSender)); if not DeleteFile(FFileName) then FOnDisplayStatus(strErrorDeletingFile + FFileName, false, 0, 0, IFF(Assigned(FSender), FSender)); end; end;
end.
|
|
|
Post by Kevin on Nov 28, 2007 21:04:13 GMT -5
Very cool! Good job!
You probably should download VCLZip 3.10 which is now available. There is a fix of a problem that could cause VCLZip to leave a directory open when using threads in version 3.06.
|
|
|
Post by otomazeli on Nov 29, 2007 9:39:54 GMT -5
Thanks for the advice, I will download the new version.
Best regards,
|
|