1 Connect to the remote server
procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);
2 Change the directory
procedure ChangeDir(const ADirName: string);
3 Downloads
procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;
procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;
4 Upload
procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;
procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;
5 Delete
procedure Delete(const AFilename: string);
Determine whether to connect
if then
begin
...........
end;
Quote others and take notes for your future
Now many applications need to upload and download large files, and uploading large files through HTTP has certain limitations. Fortunately, FTP, as a very old and very mature protocol, can efficiently and stably complete the upload and download of large files, and can perfectly realize the retransmission. Take the movie server management program I wrote for example. After comparing various solutions, I found that using FTP can perfectly implement the requirements. However, it is more troublesome to implement FTP through the WinSocket library. Fortunately, there is Indy - a component package that wraps most network protocols.
With Indy, programmers can program through blocking, leaving aside the crappy Winsocket asynchronous mode and use the same blocking programming mode as on Unix systems. In this way, programmers can handle the program's running process well.
Next, we enter Indy's TIdFtp world.
1. Description of the control
Using the TIdFtp control in Indy 9, you can upload and download files through FTP.
2. Specific use of controls
(1) Control properties settings
The default attribute is, and the attributes directly related to the server connection, such as the host name and user, are set when establishing a connection. What needs to be set are the values of the two attributes RecvBufferSize and SendBufferSize. In addition, you need to specify the TransferType attribute according to the file type to be transferred, and other attributes can be set according to the default value.
RecvBufferSize Description (default is 8192 bytes): This property is an integer variable that specifies the size of the accept buffer used for the connection.
SendBufferSize Description (default value is 32768 bytes): This property is also an integer variable, which specifies the maximum value of the send buffer used for the connection. This property can be used in TStream when in the WriteStream method to specify the number of blocks to send. If the content to be sent is greater than the value of this attribute, the sent content is sent into multiple blocks to send.
TransferType description (default is ftBinary): This property is a TIdFTPTransferType variable. Used to specify whether the transfer content is a binary file (ftBinary) or an ASCII file (ftASCII). Applications need to use binary methods to transfer executable files, compressed files, and multimedia files; and use ASCII methods to transfer text-type data such as text or hypertext.
(2) Event response of the control
OnDisconnected response: TNotifyEvent class, used to respond to disconnect events. When the Disconnect method is called to close the Socket, the response is triggered. The application must specify the process of responding to the event in order to correspond to the disconnect event.
OnStatus Response: TIdStatusEvent class. This response is triggered when the status of the current connection changes. This event can be triggered by the DoStatus method and provided to the event controller attribute. axStatus is the TIdStatus value of the current connection; aaArgs is an optional parameter for formatting functions, which will be used to construct text messages representing the current connection status.
OnWork Response: OnWord is the response controller of TWorkEvent class events. OnWork is used to associate DoWork methods to notify Indy components and classes when a buffer read and write operation is called. It is generally used to control the update of progress bars and window elements. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCount indicates the byte count of the current operation.
OnWorkBegin Response: TWorkBeginEvent Class. When the buffer read and write operation is initialized, the event is associated with the BeginWork method to notify Indy components and classes. It is generally used to control the update of progress bars and window elements. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCountMax is used to indicate the maximum number of bytes of the operation sent to the OnWorkBegin event, and a value of 0 represents unknown.
OnWorkEnd response: TWorkEndEvent class. When the buffer read and write operation terminates, the event associates the EndWork method to notify the Indy component and class. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCount represents the number of bytes of the operation.
In incident response, the above five incident responses are mainly used to control the program. In general, the interface notification of disconnection is set in OnDisconnected; the status of the current operation is set in OnStatus; the status bar and other parameters in transmission are displayed in OnWork; and the interface at the start of transmission and end of transmission is set in OnWorkBegin and OnWorkEnd respectively.
(3) Connect to the remote server
After setting control properties and implementing the control event response, you can interact and transmit with the server. Before connecting, you should first determine whether IdFtp is in the connection state. If Connected is False, the settings of some TCP class attributes related to the server connection are specified through interface controls or other means, namely: Host (host name): String, Username: String, Password: String, and Port can also be specified. Then call the Connect method to connect to the remote server. If no exception occurs, the connection is successfully established.
Process description: procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);
This process connects to the remote FTP server
Attribute: AAutoLogin: boolean = True
Automatically log in after connection, this parameter defaults to True.
const ATimeout: Integer = IdTimeoutDefault
Timeout time, unit: seconds.
Sample code:
if then try
if TransferrignData then ;
;
finally
end
else with IdFTP1 do try
Username := ;
Password := ;
Host := ;
Connect;
ChangeDir();
finally
end;
(4) Change the directory
After the connection is established, you can change the directory where the current FTP session is located. In the case of known absolute paths, you can directly call ChangeDir(const ADirName: string) method to convert the directory. ADirName represents the file system directory on the server. In addition, you can also call ChangeDirUp to return to the previous directory.
If the path is unknown, you can obtain the current directory structure of the remote server through the List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean) procedure. At this time, the TransferType must be set to ftASCII (ASCII mode), where: ADest saves the current directory structure, and the list can be called in subsequent programs. In addition, you can obtain the current directory name through the RetrieveCurrentDir method.
Process description:
procedure ChangeDir(const ADirName: string);
Change the working directory
property
const ADirName: string
Directory description of remote server
Note: This process actually implements the FTP CWD command.
procedure ChangeDirUp;
Go to the previous directory
function RetrieveCurrentDir: string;
This function returns the current directory name
procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean);
List all files and subdirectories of the current directory and their properties
parameter:
ADest: TStrings
Save file and subdirectories return results
const ASpecifier: string =
File mask, used to list files that meet the criteria
const ADetails: boolean = true
Includes file and subdirectory properties
property DirectoryListing: TIdFTPListItems;
Returns a list of files and directory structures
Sample code:
LS := ;
try
(DirName);
:= ftASCII;
:= ;
;
(LS);
(LS);
if > 0 then
if AnsiPos(total, [0]) > 0 then (0);
finally
;
end;
(5) Download Implementation
Before downloading, you must check whether [sCurrFile].ItemType is a file. If it is returned as ditDirectory, it means that the current file name is a directory. It cannot be downloaded and must be directed to the file. If it is a file, you can download it. Before downloading, set the transfer type to a binary file and specify the path to save locally. By calling the Get method, the file is downloaded. The download process is slow, so you can consider putting it in a thread to implement it.
Process description:
procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;
procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;
Get files from remote server.
Attribute description:
const ASourceFile: string
Source file name on the remote server
const ADestFile: string
File name saved to client
const ACanOverwrite: boolean = false
Rewrite file with the same name
AResume: Boolean = false
Whether to perform breakpoint continuous transmission
Sample code:
:= Name;
if then begin
SetFunctionButtons(false);
:= ftBinary;
BytesToTransfer := (Name);
if FileExists(Name) then begin
case MessageDlg(File aready exists. Do you want to resume the download operation?,
mtConfirmation, mbYesNoCancel, 0) of
mrYes: begin
BytesToTransfer := BytesToTransfer - FileSizeByName(Name);
(Name, , false, true);
end;
mrNo: begin
(Name, , true);
end;
mrCancel: begin
exit;
end;
end;
end
else begin
(Name, , false);
end;
(6) Uploading implementation
The upload implementation is similar to download, and you can use the put method.
Process description:
procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;
procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;
Upload files to server
Attribute description:
const ASourceFile: string
The file to be uploaded
const ADestFile: string =
Target file name on the server
const AAppend: boolean = false
Whether to continue uploading
Code example:
if then begin
if then try
:= ftBinary;
(, ExtractFileName());
//You can add code to change the directory here;
finally
// Complete the removal work
end;
end;
(7) Deletion implementation
Delete files use the Delete method, which deletes the specified file, and the delete object must be a file. If you want to delete the directory, use the RemoveDir method.
Process description:
procedure Delete(const AFilename: string);
Delete files
procedure RemoveDir(const ADirName: string);
Delete folders. Delete folders according to different servers have different requirements. Some servers do not allow deleting non-empty folders, and programmers need to add code to clear the directory.
The parameters of the above two processes are the target names
Code example:
if not then exit;
Name := [iCurrSelect].FileName;
if [iCurrSelect].ItemType = ditDirectory then try
(Name);
finally
end
else
try
(Name);
finally
end;
(8) The implementation of backward
Back is actually a directory operation. It can be implemented simply by changing the current directory to... or by returning to the previous directory.
(9) Cancelled implementation
During the transmission of IdFtp, the current operation can be cancelled at any time using the abort method. The OnWork event implementation can be implemented to determine when to cancel the operation.
Code example:
//OnClick response of Cancel button
procedure (Sender: TObject);
begin
AbortTransfer := true;
end;
//IdFTP's OnWork incident response
procedure TMainForm.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
...
if AbortTransfer then ;
AbortTransfer := false;
end;
(10) Implementation of breakpoint continuous transmission
The interruption of breakpoint transmission means that at the beginning of the upload or download process, it determines whether the transferred file has been transferred. If the transmission is not completed successfully, the transmission work will continue at the last interrupt. Implementing this function requires two important operations. First, it is to judge the file size information, and second, it is to specify the upload behavior in the transmission process Get and Put.
To determine the size of the file on the server, use the function Size(FileName). During the download process, compare the information of the local file and the remote file, and then specify AResume := True in Get. The same is true for uploading, just specify Put's AAppend := True.
As we mentioned earlier, most of Indy's network operations are blocking mode, and TIdFtp is no exception. In this way, the user interface is temporarily frozen during the operation process of the above operations, and you must wait for the call to return before the user interface response can continue. Therefore, in actual programming, multi-threading methods need to be used to ensure the response of the user interface. Windows systems can use CreateThread system calls to create threads, but developers need to do a lot of extra work to ensure thread synchronization and other issues. Indy also includes a multi-threaded control TIdThreadComponent. In comparison, this control is more convenient and easier to control when implementing multi-threading. I will introduce to you how to use TIdThreadCOMponent in a subsequent article
procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);
2 Change the directory
procedure ChangeDir(const ADirName: string);
3 Downloads
procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;
procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;
4 Upload
procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;
procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;
5 Delete
procedure Delete(const AFilename: string);
Determine whether to connect
if then
begin
...........
end;
Quote others and take notes for your future
Now many applications need to upload and download large files, and uploading large files through HTTP has certain limitations. Fortunately, FTP, as a very old and very mature protocol, can efficiently and stably complete the upload and download of large files, and can perfectly realize the retransmission. Take the movie server management program I wrote for example. After comparing various solutions, I found that using FTP can perfectly implement the requirements. However, it is more troublesome to implement FTP through the WinSocket library. Fortunately, there is Indy - a component package that wraps most network protocols.
With Indy, programmers can program through blocking, leaving aside the crappy Winsocket asynchronous mode and use the same blocking programming mode as on Unix systems. In this way, programmers can handle the program's running process well.
Next, we enter Indy's TIdFtp world.
1. Description of the control
Using the TIdFtp control in Indy 9, you can upload and download files through FTP.
2. Specific use of controls
(1) Control properties settings
The default attribute is, and the attributes directly related to the server connection, such as the host name and user, are set when establishing a connection. What needs to be set are the values of the two attributes RecvBufferSize and SendBufferSize. In addition, you need to specify the TransferType attribute according to the file type to be transferred, and other attributes can be set according to the default value.
RecvBufferSize Description (default is 8192 bytes): This property is an integer variable that specifies the size of the accept buffer used for the connection.
SendBufferSize Description (default value is 32768 bytes): This property is also an integer variable, which specifies the maximum value of the send buffer used for the connection. This property can be used in TStream when in the WriteStream method to specify the number of blocks to send. If the content to be sent is greater than the value of this attribute, the sent content is sent into multiple blocks to send.
TransferType description (default is ftBinary): This property is a TIdFTPTransferType variable. Used to specify whether the transfer content is a binary file (ftBinary) or an ASCII file (ftASCII). Applications need to use binary methods to transfer executable files, compressed files, and multimedia files; and use ASCII methods to transfer text-type data such as text or hypertext.
(2) Event response of the control
OnDisconnected response: TNotifyEvent class, used to respond to disconnect events. When the Disconnect method is called to close the Socket, the response is triggered. The application must specify the process of responding to the event in order to correspond to the disconnect event.
OnStatus Response: TIdStatusEvent class. This response is triggered when the status of the current connection changes. This event can be triggered by the DoStatus method and provided to the event controller attribute. axStatus is the TIdStatus value of the current connection; aaArgs is an optional parameter for formatting functions, which will be used to construct text messages representing the current connection status.
OnWork Response: OnWord is the response controller of TWorkEvent class events. OnWork is used to associate DoWork methods to notify Indy components and classes when a buffer read and write operation is called. It is generally used to control the update of progress bars and window elements. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCount indicates the byte count of the current operation.
OnWorkBegin Response: TWorkBeginEvent Class. When the buffer read and write operation is initialized, the event is associated with the BeginWork method to notify Indy components and classes. It is generally used to control the update of progress bars and window elements. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCountMax is used to indicate the maximum number of bytes of the operation sent to the OnWorkBegin event, and a value of 0 represents unknown.
OnWorkEnd response: TWorkEndEvent class. When the buffer read and write operation terminates, the event associates the EndWork method to notify the Indy component and class. AWorkMode represents the current operation mode, where: the wmRead-component is reading data; the wmWrite-component is sending data. AWorkCount represents the number of bytes of the operation.
In incident response, the above five incident responses are mainly used to control the program. In general, the interface notification of disconnection is set in OnDisconnected; the status of the current operation is set in OnStatus; the status bar and other parameters in transmission are displayed in OnWork; and the interface at the start of transmission and end of transmission is set in OnWorkBegin and OnWorkEnd respectively.
(3) Connect to the remote server
After setting control properties and implementing the control event response, you can interact and transmit with the server. Before connecting, you should first determine whether IdFtp is in the connection state. If Connected is False, the settings of some TCP class attributes related to the server connection are specified through interface controls or other means, namely: Host (host name): String, Username: String, Password: String, and Port can also be specified. Then call the Connect method to connect to the remote server. If no exception occurs, the connection is successfully established.
Process description: procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);
This process connects to the remote FTP server
Attribute: AAutoLogin: boolean = True
Automatically log in after connection, this parameter defaults to True.
const ATimeout: Integer = IdTimeoutDefault
Timeout time, unit: seconds.
Sample code:
if then try
if TransferrignData then ;
;
finally
end
else with IdFTP1 do try
Username := ;
Password := ;
Host := ;
Connect;
ChangeDir();
finally
end;
(4) Change the directory
After the connection is established, you can change the directory where the current FTP session is located. In the case of known absolute paths, you can directly call ChangeDir(const ADirName: string) method to convert the directory. ADirName represents the file system directory on the server. In addition, you can also call ChangeDirUp to return to the previous directory.
If the path is unknown, you can obtain the current directory structure of the remote server through the List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean) procedure. At this time, the TransferType must be set to ftASCII (ASCII mode), where: ADest saves the current directory structure, and the list can be called in subsequent programs. In addition, you can obtain the current directory name through the RetrieveCurrentDir method.
Process description:
procedure ChangeDir(const ADirName: string);
Change the working directory
property
const ADirName: string
Directory description of remote server
Note: This process actually implements the FTP CWD command.
procedure ChangeDirUp;
Go to the previous directory
function RetrieveCurrentDir: string;
This function returns the current directory name
procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean);
List all files and subdirectories of the current directory and their properties
parameter:
ADest: TStrings
Save file and subdirectories return results
const ASpecifier: string =
File mask, used to list files that meet the criteria
const ADetails: boolean = true
Includes file and subdirectory properties
property DirectoryListing: TIdFTPListItems;
Returns a list of files and directory structures
Sample code:
LS := ;
try
(DirName);
:= ftASCII;
:= ;
;
(LS);
(LS);
if > 0 then
if AnsiPos(total, [0]) > 0 then (0);
finally
;
end;
(5) Download Implementation
Before downloading, you must check whether [sCurrFile].ItemType is a file. If it is returned as ditDirectory, it means that the current file name is a directory. It cannot be downloaded and must be directed to the file. If it is a file, you can download it. Before downloading, set the transfer type to a binary file and specify the path to save locally. By calling the Get method, the file is downloaded. The download process is slow, so you can consider putting it in a thread to implement it.
Process description:
procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;
procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;
Get files from remote server.
Attribute description:
const ASourceFile: string
Source file name on the remote server
const ADestFile: string
File name saved to client
const ACanOverwrite: boolean = false
Rewrite file with the same name
AResume: Boolean = false
Whether to perform breakpoint continuous transmission
Sample code:
:= Name;
if then begin
SetFunctionButtons(false);
:= ftBinary;
BytesToTransfer := (Name);
if FileExists(Name) then begin
case MessageDlg(File aready exists. Do you want to resume the download operation?,
mtConfirmation, mbYesNoCancel, 0) of
mrYes: begin
BytesToTransfer := BytesToTransfer - FileSizeByName(Name);
(Name, , false, true);
end;
mrNo: begin
(Name, , true);
end;
mrCancel: begin
exit;
end;
end;
end
else begin
(Name, , false);
end;
(6) Uploading implementation
The upload implementation is similar to download, and you can use the put method.
Process description:
procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;
procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;
Upload files to server
Attribute description:
const ASourceFile: string
The file to be uploaded
const ADestFile: string =
Target file name on the server
const AAppend: boolean = false
Whether to continue uploading
Code example:
if then begin
if then try
:= ftBinary;
(, ExtractFileName());
//You can add code to change the directory here;
finally
// Complete the removal work
end;
end;
(7) Deletion implementation
Delete files use the Delete method, which deletes the specified file, and the delete object must be a file. If you want to delete the directory, use the RemoveDir method.
Process description:
procedure Delete(const AFilename: string);
Delete files
procedure RemoveDir(const ADirName: string);
Delete folders. Delete folders according to different servers have different requirements. Some servers do not allow deleting non-empty folders, and programmers need to add code to clear the directory.
The parameters of the above two processes are the target names
Code example:
if not then exit;
Name := [iCurrSelect].FileName;
if [iCurrSelect].ItemType = ditDirectory then try
(Name);
finally
end
else
try
(Name);
finally
end;
(8) The implementation of backward
Back is actually a directory operation. It can be implemented simply by changing the current directory to... or by returning to the previous directory.
(9) Cancelled implementation
During the transmission of IdFtp, the current operation can be cancelled at any time using the abort method. The OnWork event implementation can be implemented to determine when to cancel the operation.
Code example:
//OnClick response of Cancel button
procedure (Sender: TObject);
begin
AbortTransfer := true;
end;
//IdFTP's OnWork incident response
procedure TMainForm.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
...
if AbortTransfer then ;
AbortTransfer := false;
end;
(10) Implementation of breakpoint continuous transmission
The interruption of breakpoint transmission means that at the beginning of the upload or download process, it determines whether the transferred file has been transferred. If the transmission is not completed successfully, the transmission work will continue at the last interrupt. Implementing this function requires two important operations. First, it is to judge the file size information, and second, it is to specify the upload behavior in the transmission process Get and Put.
To determine the size of the file on the server, use the function Size(FileName). During the download process, compare the information of the local file and the remote file, and then specify AResume := True in Get. The same is true for uploading, just specify Put's AAppend := True.
As we mentioned earlier, most of Indy's network operations are blocking mode, and TIdFtp is no exception. In this way, the user interface is temporarily frozen during the operation process of the above operations, and you must wait for the call to return before the user interface response can continue. Therefore, in actual programming, multi-threading methods need to be used to ensure the response of the user interface. Windows systems can use CreateThread system calls to create threads, but developers need to do a lot of extra work to ensure thread synchronization and other issues. Indy also includes a multi-threaded control TIdThreadComponent. In comparison, this control is more convenient and easier to control when implementing multi-threading. I will introduce to you how to use TIdThreadCOMponent in a subsequent article