File Retrieval: Using the FTP Agent (Part II)
Example 2 is similar to
Example 1, except that it uses a separate thread to retrieve the file asynchronously. The program follows these steps:
1. Creates an FTP agent object that establishes a connection with an FTP server.
2. Performs login negotiation.
3. Creates a separate thread for get() so that file retrieval can be performed asynchronously.
4. Uses the
RWStreamCoupler mechanism to save the contents of the remote file in a local file.
5. Closes the data connection.
NOTE: For more information on the IOU feature and the different ways that IOU results can be redeemed with or without blocking a current thread, see
Multithreading and IOUs and the
’s Guide.
NOTE: Servers and files shown in the code might not exist and are included as examples only.
Example 2 – Retrieving a file asynchronously
try {
RWFtpAgent agent("ftp.roguewave.com",
"anonymous", "me@roguewave.com"); // 1
RWTIOUResult<RWSocketPortal> sPortal =
agent.get("remote_file"); // 2
// Do other things here // 3
RWPortalIStream istrm(sPortal.redeem()); // 4
ofstream ostrm("local file"); // 5
RWStreamCoupler couple; // 6
couple(istrm, ostrm); // 7
bool dataClosed = agent.dataClose(); // 8
} // 9
catch (const RWxmsg& msg) { //10
cout << "ERROR: " << msg.why() << endl;
}
NOTE: In this example, FTP data retrieval is joined to a local file where the data is stored. This mechanism may also be used to automate copying one file to another.
The actual data transfer process, accomplished by the
RWStreamCoupler mechanism, is completed within the main thread, which could cause a block when transferring large files. You may want to consider moving all code related to data transfer to a separate function, and then use the Threads Module thread-creation mechanisms to launch that function in a new thread so that the main thread does not block during the data transfer.