You are on page 1of 5

File Transfer Protocol

Transferring files from one machine to another is a fundamental task in today's distributed environment. Most techies know all of the commands to connect to a remote FTP server, find a file or files, setup the transfer type, and grab the files your want. A typical FTP session might look as follows:
C:\> ftp 192.168.1.99 Connected to 192.168.1.99. 220 WGB01 FTP server (Version wu-2.6.2-5) ready. User (192.168.1.99:(none)): myusername 331 Password required for myusername. Password: 230 User myusername logged in. ftp> cd /apps/mydir ftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for directory listing. total 6160 -rw-r--r-1 501 100 3147032 Mar 31 13:37 myfile.pdf

226 Transfer complete. ftp: 101 bytes received in 0.58Seconds 0.17Kbytes/sec. ftp> lcd c:\download ftp> bin ftp> get myfile.pdf

The steps outlined in this session are as follows: 1. Connect to the server 2. Logon with a username and password 3. Change directory to "/apps/mydir" (cd) 4. Get a listing the files in that directory (ls) 5. Change the local directory to "c:\download" (lcd) 6. Set the transfer mode to binary (bin) 7. Retrieve the file "myfile.pdf" from the server (get)

Each of these steps require an action from the FTP client and the FTP server and then error checking at every stage. The bottom line is that it is a lot of work. Now consider the code in listing 1.

Listing 1. getDataFiles() method


... import org.apache.commons.net.ftp.*; ...

public static void getDataFiles( String server, String username, String password, String folder, String destinationFolder, Calendar start, Calendar end ) { try { // Connect and logon to FTP Server FTPClient ftp = new FTPClient(); ftp.connect( server ); ftp.login( username, password ); System.out.println("Connected to " + server + "."); System.out.print(ftp.getReplyString());

// List the files in the directory ftp.changeWorkingDirectory( folder ); FTPFile[] files = ftp.listFiles(); System.out.println( "Number of files in dir: " + files.length ); DateFormat df = DateFormat.getDateInstance( DateFormat.SHORT ); for( int i=0; i<files.length; i++ ) { Date fileDate = files[ i ].getTimestamp().getTime(); if( fileDate.compareTo( start.getTime() ) >= 0 && fileDate.compareTo( end.getTime() ) <= 0 ) {

// Download a file from the FTP Server System.out.print( df.format( files[ i ].getTimestamp().getTime() ) ); System.out.println( "\t" + files[ i ].getName() ); File file = new File( destinationFolder + File.separator + files[ i ].getName() ); FileOutputStream fos = new FileOutputStream( file ); ftp.retrieveFile( files[ i ].getName(), fos ); fos.close(); file.setLastModified( fileDate.getTime() ); } }

// Logout from the FTP Server and disconnect ftp.logout(); ftp.disconnect();

} catch( Exception e ) { e.printStackTrace(); } }

To compile listing 1, you will need to download the Commons/Net library from: http://jakarta.apache.org/commons/net/index.html And then setup your CLASSPATH to include the following file distributed in that download:
commons-net-1.0.0.jar

The getDataFiles()connects to an FTP server using a provided username and password, changes to a specified directory, and downloads all files in a date range to a specified local directory. All of this is accomplished through two of the Commons/Net classes: FTPClient: used to connect and logon to a server, navigate the directory structure, list files, upload and download files, and log out and disconnect from the server FTPFile: used to discover file properties

The FTPClient class is the high-level front-end to connecting to FTP servers. It provides the following functionality (this list is a subset of the methods provided): connect(String server) - connect to a server disconnect() - disconnect from a server login(String username, String password) - login to an FTP server logout() - logout from the FTP server changeWorkingDirectory(String pathname) - change the current working directory on the FTP server FTPFile[] listFiles() - list the files in the current working directory on the FTP server String[] listNames() - list the filenames in the current working directory on the FTP server String[] listNames(String pathname) - list the filenames in the specified directory on the FTP server makeDirectory(String pathname) - create the new specified directory rename(String from, String to) - rename a file on the FTP server storeFile(String remoteName, InputStream local) - upload the file from the specified java.io.InputStream to the remoteName in the current working directory retrieveFile(java.lang.String remoteName, OutputStream local) - downloads the specified remoteName file from the current working directory to the specified java.io.OutputStream Obtaining a file listing provides an array of FTPFiles. The FTPFile class provides the following functionality: String getName() - returns the name of the file String getGroup() - returns the group that this file belongs to String getUser() - returns the user that owns the file long getSize() - returns size of the file int getType() - returns the type of the file: DIRECTORY_TYPE, FILE_TYPE, SYMBOLIC_LINK_TYPE, UNKNOWN_TYPE

boolean isDirectory() - returns true if this file is a directory boolean isFile() - returns true if this file is a file (not a directory) boolean isSymbolicLink() - returns true if this file is a symbolic link Calendar getTimestamp() - returns the timestamp that the file was last modified

Listing 1 shows a function that in a very small number of lines of code accomplishes an incredible number of tasks. The total time to write and test this code was about 30 minutes, but if you had to focus on the details of the FTP protocol, then that estimate could easily be increased tenfold. The FTPClient and FTPFile classes allow you to focus on your business function rather than the underlying details of the transfer mechanism.

You might also like