Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Mar : Re: IdFTP.Get Not Firing OnAfterGet

www.cryer.info
Managed Newsgroup Archive

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

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive