ReadFTPFile Method
Class: FTP_SERVICE
Get file from FTP do string or local file.
=
Object.ReadFTPFile
Parameter
lcRemoteFile
Remote file name
Type Character
Direction Input
Name and Path of the file on the FTP Server to bring down.
This parameter cannot be empty.
lcData
Data or file name
Type Character
Direction Input
Data or file name for the contents of the file to be stored in.
This parameter cannot be empty.
liData
Buffer size
Type Integer
Direction Input
Optional  
liRStart
Start position of remote file
Type Integer
Direction Input
Optional  
If value 0 , then file will be read all. If value >0 , then file will be read from position.
liLStart
Start position of local file/string buffer
Type Integer
Direction Input
Optional  
If value 0 , then data will write into begin of file. If value >0 , then file will be write from into start position.
liFlags
Mode flags
Type Boolean
Direction Input
Optional  
List of types
ValueDescription
_FTPS_RWF_Resume Resume mode
_FTPS_RWF_File lcData is file name.
_FTPS_RWF_String lcData is string.
_FTPS_RWF_Rewrite Rewrite mode
lnFlag
The flags that indicate various options.
Type Numeric/Array
Direction Input
The value can be single number value of array number values. If You use single value, then passed value is equal to dwFlags parameter of API function. Value is combined with FTP_SERVICE::nCachingType's value. If this parameter ommited, then default value is FTP_TRANSFER_TYPE_UNKNOWN . Can be one of the following:
ValueDescription
FTP_TRANSFER_TYPE_ASCII Transfers the file as ASCII.
FTP_TRANSFER_TYPE_BINARY Transfers the file as binary.
Assumed from MSDN.

If you use array of numbers, then first value (_FTPS_FA_Default ) is equal to dwFlags parameter of API function. Second value (_FTPS_FA_ModeFile ) is controling flag . Can be one of the following::

ValueDescription
_FTPS_FA_MF_Error Cause error if local file doesn't exist.
_FTPS_FA_MF_Append Create new local file and add empty place.
_FTPS_FA_MF_New Create new file.
The value is ignore then you don't use _FTPS_RWF_Resume .
Return value Boolean
The return value is .T. if file is downloaded or .F. is not.
Example
LOCAL loFTP,lcPom
LOCAL ARRAY laFlags(_FTPS_FA_MaxSize)
#INCLUDE "ftp.h"
laFlags(_FTPS_FA_Default)=FTP_TRANSFER_TYPE_BINARY
laFlags(_FTPS_FA_ModeFile)=_FTPS_FA_MF_Append

SET PROCEDURE TO ftp.prg ADDITIVE 
loFTP=CREATEOBJECT('_myftp') 

IF loFTP.OpenInternet("ABONNE", "PWD", "10.10.10.10", "21")

   * Read remote file from bottom to local file
   IF ?loFTP.ReadFtpFile("any.txt","local.txt",1000)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF

   * Read remote file from 10. byte (resume mode) to local file
   IF loFTP.ReadFtpFile("any.txt","local.txt",1000,10)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF

   * Read remote file from bottom to string
   lcPom=""
   IF loFTP.ReadFtpFile("any.txt",@lcPom,1000,0,0,_FTPS_RWF_String)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF
   ?LEN(lcPom)

   * Read remote file from 10. byte to string
   lcPom="Ahoj vole12ABCD"
   If loFTP.ReadFtpFile("any.txt",@lcPom,1000,10,0,_FTPS_RWF_String)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF
   ?LEN(lcPom)

   * Read remote file from bottom to local file into new position - 10. byte
   IF loFTP.ReadFtpFile("any.txt","local.txt",1000,0,10,_FTPS_RWF_Rewrite)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF

   * Read remote file from 10. byte to local file into new position - 20. byte
   IF loFTP.ReadFtpFile("tags.html","local.txt",1000,10,20,_FTPS_RWF_Rewrite)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF

   * Read remote file from 10. byte to local file into new position - 20. byte, but with controling file mode flag
   DELETE FILE local.txt
   IF loFTP.ReadFtpFile("tags.html","local.txt",1000,10,20,_FTPS_RWF_Rewrite,@laFlags)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF


   * Read remote file from bottom to string into new position - 10. byte
   lcPom="Ahoj vole12ABCD"
   IF loFTP.ReadFtpFile("any.txt",@lcPom,1000,0,10,_FTPS_RWF_String+_FTPS_RWF_Rewrite)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF
   ?LEN(lcPom)

   * Read remote file from 10. byte to string into new position - 20. byte
   lcPom="Ahoj vole12ABCDAhoj vole12ABCD"
   IF loFTP.ReadFtpFile("any.txt",@lcPom,1000,10,20,_FTPS_RWF_String+_FTPS_RWF_Rewrite)
      ?STRTRAN("File %File% downloaded","%File%","any.txt")
   ELSE
      ?loFTP.GetExtendedErrorCode(),loFTP.GetExtendedErrorMsg()
   ENDIF
   ?LEN(lcPom)

   =loFTP.CloseInternet() 
ENDIF
RELEASE PROCEDURE ftp.prg

DEFINE CLASS _myFTP AS FTP_SERVICE
   PROCEDURE BeforeReadFTPFile(lcRemoteFile, lcData,liData,liRStart,liLStart,liFlags,lnFlag)
      ?PROGRAM(16)
      ?CHR(9),lcRemoteFile,liData,liRStart,liLStart,liFlags
   ENDPROC

   PROCEDURE AfterReadFTPFile(lcRemoteFile, lcData,liData,liRStart,liLStart,liFlags,lnFlag,fResult)
      ?PROGRAM(16)
      ?CHR(9),lcRemoteFile,liData,liRStart,liLStart,liFlags,fResult
   ENDPROC

   PROCEDURE AtReadFTPFile(lcRemoteFile, lcData,liData,liRStart,liLStart,liFlags,lnFlag,lcBuffer,fResult)
      ?PROGRAM(16)
      ?CHR(9),lcRemoteFile,liData,liRStart,liLStart,liFlags,lcBuffer,fResult
   ENDPROC
ENDDEFINE 
See also
Expand/Collapse source code of procedure ReadFTPFile Source Code
      LPARAMETERS INP lcRemoteFile,INP lcData,OPT_INP liData,OPT_INP liRStart,OPT_INP liLStart,OPT_INP liFlags,OPT_INP lnFlag
      LOCAL fResult,lihFTP,lcBuffer,liData,liRead,lihFile,llFast,lcAll,llAppend,liFSize,liModeFile
      lihFile=0
      liData=IIF(PCOUNT()<3,512,liData)
      liData=IIF(liData<=0,512,liData)

      liRStart=IIF(PCOUNT()<4,0,liRStart)
      liLStart=IIF(PCOUNT()<5,0,liLStart)
      liFlags=IIF(PCOUNT()<6,_FTPS_RWF_Resume+_FTPS_RWF_File,liFlags)
      lnFlag=IIF(PCOUNT()<7,FTP_TRANSFER_TYPE_UNKNOWN,lnFlag)

      liModeFile=IIF(TYPE("lnFlag("+LTRIM(STR(_FTPS_FA_ModeFile,11))+")")="N",lnFlag(_FTPS_FA_ModeFile),0)

      IF !BITTEST(liFlags,0) && File?
         llFast=VAL(STRTRAN(SUBS(VERSION(),LEN("Visual FoxPro ")+1,2),"0",""))>6
         IF !llFast
            lihFile=FOPEN(lcData,0)
            IF lihFile<=0
               IF liModeFile=_FTPS_FA_MF_Error
                  RETURN .F.
               ENDIF
               lihFile=FCREATE(lcData,0)

               DO CASE
                  CASE liModeFile=_FTPS_FA_MF_New OR IIF(BITTEST(liFlags,1),liLStart,liRStart)=0

                  CASE lihFile<=0
                       RETURN .F.

                  CASE liModeFile=_FTPS_FA_MF_Append
                       IF BITTEST(liFlags,1) && rewrite, skip to new position
                          =FCHSIZE(lihFile,liLStart+1)
                          =FSEEK(lihFile,liLStart,0)
                       ELSE
                          =FCHSIZE(lihFile,liRStart+1)
                          =FSEEK(lihFile,liRStart,0) && resume native mode
                       ENDIF


               ENDCASE

            ELSE
               IF lihFile<=0
                  RETURN .F.
               ENDIF

               =IIF(BITTEST(liFlags,1),; && rewrite, skip to new position
                    FSEEK(lihFile,liLStart,0),;
                    FSEEK(lihFile,liRStart,0)) && resume native mode
            ENDIF
         ELSE
            IF LEN(SYS(2000,lcData))=0 && local file not exist
               DO CASE
                  CASE liModeFile=_FTPS_FA_MF_New OR IIF(BITTEST(liFlags,1),liLStart,liRStart)=0
                       lcAll=""

                  CASE liModeFile=_FTPS_FA_MF_Error
                       RETURN .F.

                  CASE liModeFile=_FTPS_FA_MF_Append
                       lcAll=IIF(BITTEST(liFlags,1),; && rewrite, skip to new position
                                 REPL(CHR(0),liLStart),REPL(CHR(0),liRStart))

                  OTHERWISE

               ENDCASE

            ELSE
               lcAll=FILETOSTR(lcData)
               lcAll=IIF(BITTEST(liFlags,1),; && rewrite, skip to new position
                         LEFT(lcAll,liLStart),LEFT(lcAll,liRStart))
            ENDIF


         ENDIF
      ELSE
         IF TYPE("lcData")#"C"
            RETURN .F.
         ENDIF
         lcData=IIF(BITTEST(liFlags,1),; && rewrite, skip to new position
                    LEFT(lcData,liLStart),LEFT(lcData,liRStart))
         llFast=.T.
      ENDIF

      IF This.OpenFTPConnection(This.cCurrentDir) && Open an FTP Handle
         lcRemoteFile = lcRemoteFile + cNULL

         =This.BeforeReadFTPFile(@lcRemoteFile, @lcData,liData,liRStart,liLStart,liFlags,lnFlag)
         IF liRStart<=0 && All data
            STORE FtpOpenFile(This.nConnect_Handle, @lcRemoteFile, GENERIC_READ, ;
                              BITOR(This.nCachingType,lnFlag), 0) TO fResult,lihFTP
            =This.GetExtendedError()
         ELSE
            fResult=0
            =This.FTPCommand("REST "+LTRIM(STR(liRStart,11)), FTP_TRANSFER_TYPE_BINARY,0,.NULL.)
            IF This.FTPCommand("RETR "+lcRemoteFile, FTP_TRANSFER_TYPE_BINARY,0,@lihFTP)
               fResult=1
            ENDIF
         ENDIF

         IF fResult #0 && OK, FTP file is openned
            lii=0
            STORE 1 TO fResult,liRead

            DO WHILE liRead>0
               liRead=0
               lcBuffer=SPACE(liData)
               fResult = InternetReadFile(lihFTP, @lcBuffer, liData, @liRead)
               =This.GetExtendedError()
               =This.AtReadFTPFile(@lcRemoteFile, @lcData,liData,liRStart,liLStart,liFlags,lnFlag,@lcBuffer,fResult)

               IF !BITTEST(liFlags,0) && File?
                  IF llFast AND liRead>0
                     IF LEN(lcAll)+liRead>_FTPS_MaxFileSize
                        =STRTOFILE(lcAll,lcData,llAppend)
                        llAppend=.T.
                        lcAll=""
                     ENDIF
                     lcAll=lcAll+LEFT(lcBuffer,liRead)
                  ELSE
                     IF liRead>0
                        =FWRITE(lihFile,LEFT(lcBuffer,liRead),liRead)
                     ENDIF
                  ENDIF
               ELSE
                  lcData=lcData+LEFT(lcBuffer,liRead)
               ENDIF
               lii=lii+liRead
            ENDDO

            IF !BITTEST(liFlags,0)
                =IIF(llFast AND LEN(lcAll)>0,; && File?
                     STRTOFILE(lcAll,lcData,llAppend),.T.)
                =IIF(lihFile>0 AND !llFast,FCLOSE(lihFile),.T.)
            ENDIF
            =InternetCloseHandle(lihFTP)

            =IIF(liRStart>0,This.FTPCommand("NOOP", FTP_TRANSFER_TYPE_BINARY,0,.NULL.),.T.)
         ENDIF

         =This.AfterReadFTPFile(@lcRemoteFile, @lcData,liData,liRStart,liLStart,liFlags,lnFlag,fResult)
         =IIF(This.lMultiOperations,.T.,This.CloseFTPConnection())   && Close FTP Handle
         RETURN  fResult = 1
      ENDIF
      RETURN .F.