Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Mar : Re: IdFTP.Get Not Firing OnAfterGet
| Subject: | Re: IdFTP.Get Not Firing OnAfterGet |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Wed, 14 Mar 2007 13:04:34 |
"Richard Stephens" <rick@almsysinc.com> wrote in message
news:45f8479a$1@newsgroups.borland.com...
> It does not fire it. I placed a ShowMessage statement in the
> OnAfterGet routine. It never showed and the file downloaded fine.
That is physically impossible. Look at Get()'s source code for
yourself:
procedure TIdFTP.Get(const ASourceFile: string; ADest: TIdStream;
AResume: Boolean = False);
begin
ClearSSCN;
AResume := AResume and CanResume;
DoBeforeGet;
InternalGet('RETR ' + ASourceFile, ADest, AResume);
DoAfterGet(ADest); // <-- OnAfterGet is triggered here!!!
end;
The *only* ways for the event handler to be ignored are either 1) it
is not assigned to begin with, or 2) an exception is being raised.
> I am using the Indy 10 version that shipped with Delphi 2006
Enterprise.
Then you are using an old build. Try upgrading to the latest 10.1.6
snapshot from Indy's website.
> How does one tell what version of Indy 10 one has?
Right-click on any Indy component in the Form Designer.
> Any time that I send FALSE as AResume to the IdFTP.Get routine,
> it sends an EIdFTPFileAlreadyExists exception with the message
> "Destination file already exists".
When AResume is False (or the CanResume property is False), then the
exception is only raised when ACanOverwrite is also False and
FileExists() returns True. Regardless of the values of ACanOverwrite
and AResume, the exception is raised only when FileExists() returns
True. Look at the source code for yourself:
// Indy 10.1.6
procedure TIdFTP.Get(const ASourceFile, ADestFile: string; const
ACanOverwrite: Boolean = False; AResume: Boolean = False);
var
LDestStream: TIdStream;
begin
AResume := AResume and CanResume;
if ACanOverwrite and (not AResume) then begin
Sys.DeleteFile(ADestFile);
LDestStream := TIdFileCreateStream.Create(ADestFile);
end
else if (not ACanOverwrite) and AResume then begin
LDestStream := TIdAppendFileStream.Create(ADestFile);
end
else if not Sys.FileExists(ADestFile) then begin
LDestStream := TIdFileCreateStream.Create(ADestFile);
end
else begin
raise
EIdFTPFileAlreadyExists.Create(RSDestinationFileAlreadyExists);
end;
try
Get(ASourceFile, LDestStream, AResume);
finally
Sys.FreeAndNil(LDestStream);
end;
end;
// Indy 10.0.52
procedure TIdFTP.Get(const ASourceFile, ADestFile: string; const
ACanOverwrite: boolean = false; AResume: Boolean = false);
var
LDestStream: TFileStream;
begin
if FileExists(ADestFile) then begin
AResume := AResume and CanResume;
if ACanOverwrite and (not AResume) then begin
DeleteFile(ADestFile);
LDestStream := TFileStream.Create(ADestFile,
fmCreate);
end
else begin
if (not ACanOverwrite) and AResume then begin
LDestStream := TFileStream.Create(ADestFile,
fmOpenReadWrite or fmShareDenyWrite);
LDestStream.Position := LDestStream.Size;
end
else begin
raise
EIdFTPFileAlreadyExists.Create(RSDestinationFileAlreadyExists);
end;
end;
end
else begin
LDestStream := TFileStream.Create(ADestFile, fmCreate);
end;
try
Get(ASourceFile, LDestStream, AResume);
finally
FreeAndNil(LDestStream);
end;
end;
In both cases, the only conbination that results in the exception is
when FileExists() returns True, and ACanOverwrite and AResume are both
the same value.
> Well, the file does not exist, plain and simple.
It is physically impossible for FileExists() to return True for a
non-existant file. So obviously, you are passing in a filename that
does really exist. There is no other way for that exception to occur.
> Now, if the file does indeed exist in the target folder, then
> AResume=False does not give the exception.
When AResume is False, the existing file is deleted when ACanOverwrite
is True, and the exception is raised if ACanOverwrite is False. See
the code above.
Gambit