Uploading files to the FTP server with Java

To write Java code that uploads files from the local disk to the online FTP server, the Apache Commons Net API is a very good choice for Java developers. It's simple and makes programming with FTP easy.

1- Download the Apache Commons Net

API download Apache Commons Net API  which contains a set of network tools and supports several protocols such as: FTP, Telnet, SMTP... After uploading, the .jar file should be embedded in your project's classpath.

2- The Apache Commons Net API for file transfer via the FTP

The class  FTPClient  provides methods for transferring a local file to the online server via the FTP:
  • boolean storeFile(String remote, InputStream local)
  • OutputStream storeFileStream(String remote)
  • boolean storeUniqueFile(InputStream local)
  • boolean storeUniqueFile(String remote, InputStream local)
  • OutputStream storeUniqueFileStream()
  • OutputStream storeUniqueFileStream(String remote)
What is the difference between these methods? Well! They can be categorized as follows:
  • Store files by giving a  InputStream  of the local file (these are the methods that have a  InputStream  as a parameter). This type of methods is adopted when you don't need to know how. the  bytes  are transferred from the local file to the server. We let the system do this. processing.
  • Store files by writing to the  OutputStream  of the connection (these are the methods that have an OutputStream as an output). These types of methods are necessary when you want to control how the bytes are used. are  forwarded, by writing our own code to read the bytes  via the local file that will be saved in the remote file path through the object  OutputStream. This can be useful if you want to show the Progress  of the upload, calculating how many bytes are transferred over the file size .
The above two methods can be used in combination with:
  • Name the remote file clearly (Those methods that accept a String parameter named remote).
  • Leave the server names and the remote file with a unique name (These methods that don't have a String parameter).
Despite the complexity of these methods, Only two methods are mainly used in practice:
  • boolean storeFile(String remote,InputStream local)
  • OutputStream storeFileStream(String remote)
Apart from these six methods, there are also two others that need to be called before and after the file is downloaded:
  • boolean setFileType(int fileType): Determines the type of the file, i.e., FTP. ASCII_FILE_TYPE or FTP. BINARY_FILE_TYPE, is used to transfer the file. The default type is ASCII (plain text), but it must be made binary in order for it to work for all files. This method must be called before the file transfer begins.
  •   boolean completePendingCommand(): This method must be called after the download is complete to complete the transaction. She returns true  If the transfer is completed successfully, if not; false. The return value of this method must be checked to ensure that the upload has taken place.
    By default, FTP establishes the connection by opening a port for the client and allows the server to connect to that port. This is the active mode, but it is sometimes blocked by the firewall and the file transfer does not work. Fortunately, the FTP protocol has another mode which is the passive mode in which the connection is established, by opening a port in the server for the client to connect. This mode is not blocked by the firewall.

    So it is recommended to switch to passive mode before the start of the data transfer with the call of the FTPClient class method enterLocalPassiveMode().

    3- The steps to transfer a file in Java

    To properly write the code to transfer a file to the FTP server using the Apache Commons Net API, the following steps must be followed:
    • Connect and log in to the server.
    • Use passive mode for connection.
    • Change the type of file to be transferred to binary.
    • Create a InputStream for the local file.
    • Call one of the methods store... () to begin transferring the file. There are two scenarios:
      • Using a InputStream: This is the easiest way since you let the system take care of sending and receiving. There is no additional code, just pass the item InputStream  in the corresponding method, such as the method storeFile(String remote, InputStream local).
      • Using  OutputStream: This is more complex, but you gain more control over the data transferred. In general, one has to write a few lines of code to read bytes from  InputStream  of the local file and write those bytes to a OutputStream that is returned by the Store method... (), such as the storeFileStream(String remote).
    • Close Data Streams  InputStream  et  OutputStream.
    • Call the method completePendingCommand() to complete the transaction.
    • Disconnect from server.
    The value of the return of the methods store... () and completePendingCommand() to ensure that the upload has been completed.

    4- Java

    This code shows how to send files from the machine to the FTP server using these two methods:
    • boolean storeFile(String remote, InputStream local)
    • OutputStream storeFileStream(String remote)
    After calling the storeFile(), it is not mandatory to call the completePendingCommand(). Here is the full code:

    import java.io.File; 
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;

    public class FTPUploadFile {

    public static void main(String[] args) {
    Server String = "ServerAddress";
    int port = 21;
    String user = "username";
    String password = "yourPassword";

    FTPClient ftpClient = new FTPClient();
    try {

    ftpClient.connect(server, port);
    ftpClient.login(user, password);
    ftpClient.enterLocalPassiveMode();

    ftpClient.setFileType(FTP. BINARY_FILE_TYPE);

    // Approach 1: Upload a file using InputStream
    File file = new File("C:/plugins and styles.txt");

    String path = "plugins and styles.txt";
    InputStream inputStream = new FileInputStream(file);

    System.out.println("Start upload");
    //output of upload
    boolean res = ftpClient.storeFile(path, inputStream);
    //closes the read stream
    inputStream.close();

    if (res==true) {
    System.out.println("The file "+path+" has been successfully downloaded");
    }

    // Approach 2: Upload a file using OutputStream
    file = new File("C:/track 1.wma");
    path = "audio/track 1.wma";
    inputStream = new FileInputStream(file);

    System.out.println("Start upload");
    OutputStream outputStream = ftpClient.storeFileStream(path);
    byte[] bytesIn = new byte[4096];
    int buffer = 0;

    //as long as we haven't reached the end of the file
    System.out.println("Downloading...");
    int transferred = 0;
    int percent = 0;
    //as long as we haven't reached the end of the file
    while ((buffer = inputStream.read(bytesIn)) != -1) {
    //read the data with a buffer of 4096 bytes
    outputStream.write(bytesIn, 0, buffer);
    transferred += buffer;
    percent = (int) (transferred*100/file.length());
    System.out.println(percentage+"%");
    }
    //close write read streams
    inputStream.close();
    outputStream.close();

    //upload result
    res = ftpClient.completePendingCommand();
    if (res) {
    System.out.println("The "+path+" file has been successfully downloaded");
    }

    } catch (IOException e) {
    System.out.println(e.getMessage());
    e.printStackTrace();
    } finally {
    try {
    if (ftpClient.isConnected()) {
    //close FTP
    ftpClient.logout();
    ftpClient.disconnect();
    }
    } catch (IOException ex) {
    ex.printStackTrace();
    }
    }
    }
    }
    The execution of this code returns that the transfer has been successful:

    Start of upload
    The plugins and styles.txt file has been successfully downloaded
    Start of upload
    1%
    2%
    3%
    .
    .
    97%
    98%
    98%
    99%
    99%
    100%
    The 1.wma track file was successfully downloaded