Java, Programming

Apache Commons VFS for SFTP

apache-commons-vfs-for-sftp

In Java, using FTP to upload, download file is very easy. You can see this post: Upload Files to FTP Server using Java. Java API support FTP operation, but does not support SFTP operation.

Apache Commons VFS provides a single API for accessing various different file systems. It presents a uniform view of the files from various different sources, such as the files on local disk, on an HTTP server, or SFTP server.

Before start, Please download below library.

When download complete, please unzip and add .jar to class path.

First, create a method to concatenate Host name, Username, Password and Remote File Path in one String:

public static String createConnectionString(String hostName,
        String username, String password, String remoteFilePath) {
    // result: "sftp://user:[email protected]/resume.pdf
    return "sftp://" + username + ":" + password + "@" + hostName + "/"
            + remoteFilePath;
}

Then, create a method to setup default SFTP config:

public static FileSystemOptions createDefaultOptions()
    throws FileSystemException {
  // Create SFTP options
  FileSystemOptions opts = new FileSystemOptions();
  
  // SSH Key checking
  SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
      opts, "no");

  // Root directory set to user home
  SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);

  // Timeout is count by Milliseconds
  SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);

  return opts;
}

Write a upload file function:

public static void upload(String hostName, String username,
    String password, String localFilePath, String remoteFilePath) {
  File f = new File(localFilePath);
  if (!f.exists())
    throw new RuntimeException("Error. Local file not found");

  StandardFileSystemManager manager = new StandardFileSystemManager();

  try {
    manager.init();

    // Create local file object
    FileObject localFile = manager.resolveFile(f.getAbsolutePath());

    // Create remote file object
    FileObject remoteFile = manager.resolveFile(
        createConnectionString(hostName, username, password,
            remoteFilePath), createDefaultOptions());

    // Copy local file to sftp server
    remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);

    System.out.println("File upload success");
  } catch (Exception e) {
    throw new RuntimeException(e);
  } finally {
    manager.close();
  }
}

Now, We can test upload function is it work.

/*
 * args[0]: hostName 
 * args[1]: username 
 * args[2]: password 
 * args[3]:localFilePath 
 * args[4]: remoteFilePath
 */
public static void main(String[] args) {
    if (args.length < 5)
        throw new RuntimeException(
                "Error. Please enter "
                        + "args[0]: hostName, args[1]: username, args[2]: password, "
                        + "args[3]: localFilePath, args[4]: remoteFilePath.");
    upload(args[0], args[1], args[2], args[3], args[4]);
}

If upload file success, console will print “File upload success”.

Download file function:

public static void download(String hostName, String username,
    String password, String localFilePath, String remoteFilePath) {
  StandardFileSystemManager manager = new StandardFileSystemManager();

  try {
    manager.init();

    String downloadFilePath = localFilePath.substring(0,
        localFilePath.lastIndexOf("."))
        + "_downlaod_from_sftp"
        + localFilePath.substring(localFilePath.lastIndexOf("."),
        localFilePath.length());

    // Create local file object
    FileObject localFile = manager.resolveFile(downloadFilePath);

    // Create remote file object
    FileObject remoteFile = manager.resolveFile(
        createConnectionString(hostName, username, password,
            remoteFilePath), createDefaultOptions());

    // Copy local file to sftp server
    localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);

    System.out.println("File download success");
  } catch (Exception e) {
    throw new RuntimeException(e);
  } finally {
    manager.close();
  }
}

Check remote file is exist function:

public static boolean exist(String hostName, String username,
    String password, String remoteFilePath) {
  StandardFileSystemManager manager = new StandardFileSystemManager();
  try {
    manager.init();

    // Create remote object
    FileObject remoteFile = manager.resolveFile(
        createConnectionString(hostName, username, password,
            remoteFilePath), createDefaultOptions());

    System.out.println("File exist: " + remoteFile.exists());

    return remoteFile.exists();
  } catch (Exception e) {
    throw new RuntimeException(e);
  } finally {
    manager.close();
  }
}

Delete remote file function:

public static void delete(String hostName, String username,
    String password, String remoteFilePath) {
  StandardFileSystemManager manager = new StandardFileSystemManager();
  try {
    manager.init();

    // Create remote object
    FileObject remoteFile = manager.resolveFile(
        createConnectionString(hostName, username, password,
            remoteFilePath), createDefaultOptions());

    if (remoteFile.exists()) {
      remoteFile.delete();
      System.out.println("Delete remote file success");
    }
  } catch (Exception e) {
    throw new RuntimeException(e);
  } finally {
    manager.close();
  }
}

Complete program:

package sftp.sample;

import java.io.File;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.Selectors;
import org.apache.commons.vfs.impl.StandardFileSystemManager;
import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;

public class Main {

  /*
   * args[0]: hostName
   * args[1]: username
   * args[2]: password
   * args[3]: localFilePath
   * args[4]: remoteFilePath
   */
  public static void main(String[] args) {
    if (args.length < 5) {
      throw new RuntimeException(
          "Error. Please enter "
              + "args[0]: hostName, args[1]: username, args[2]: password, "
              + "args[3]: localFilePath, args[4]: remoteFilePath.");
    }

    upload(args[0], args[1], args[2], args[3], args[4]);
    exist(args[0], args[1], args[2], args[4]);
    download(args[0], args[1], args[2], args[3], args[4]);
    delete(args[0], args[1], args[2], args[4]);
  }

  public static void upload(String hostName, String username,
      String password, String localFilePath, String remoteFilePath) {

    File f = new File(localFilePath);
    if (!f.exists()) {
      throw new RuntimeException("Error. Local file not found");
    }

    StandardFileSystemManager manager = new StandardFileSystemManager();

    try {
      manager.init();

      // Create local file object
      FileObject localFile = manager.resolveFile(f.getAbsolutePath());

      // Create remote file object
      FileObject remoteFile = manager.resolveFile(
          createConnectionString(hostName, username, password,
              remoteFilePath), createDefaultOptions());

      // Copy local file to sftp server
      remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);

      System.out.println("File upload success");
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      manager.close();
    }
  }

  public static void download(String hostName, String username,
      String password, String localFilePath, String remoteFilePath) {

    StandardFileSystemManager manager = new StandardFileSystemManager();

    try {
      manager.init();

      String downloadFilePath = localFilePath.substring(0,
          localFilePath.lastIndexOf("."))
          + "_downlaod_from_sftp"
          + localFilePath.substring(localFilePath.lastIndexOf("."),
          localFilePath.length());

      // Create local file object
      FileObject localFile = manager.resolveFile(downloadFilePath);

      // Create remote file object
      FileObject remoteFile = manager.resolveFile(
          createConnectionString(hostName, username, password,
              remoteFilePath), createDefaultOptions());

      // Copy local file to sftp server
      localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);

      System.out.println("File download success");
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      manager.close();
    }
  }

  public static void delete(String hostName, String username,
      String password, String remoteFilePath) {
    StandardFileSystemManager manager = new StandardFileSystemManager();

    try {
      manager.init();

      // Create remote object
      FileObject remoteFile = manager.resolveFile(
          createConnectionString(hostName, username, password,
              remoteFilePath), createDefaultOptions());

      if (remoteFile.exists()) {
        remoteFile.delete();
        System.out.println("Delete remote file success");
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      manager.close();
    }
  }

  public static boolean exist(String hostName, String username,
      String password, String remoteFilePath) {
    StandardFileSystemManager manager = new StandardFileSystemManager();

    try {
      manager.init();

      // Create remote object
      FileObject remoteFile = manager.resolveFile(
          createConnectionString(hostName, username, password,
              remoteFilePath), createDefaultOptions());

      System.out.println("File exist: " + remoteFile.exists());

      return remoteFile.exists();
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      manager.close();
    }
  }

  public static String createConnectionString(String hostName,
      String username, String password, String remoteFilePath) {
    // result: "sftp://user:[email protected]/resume.pdf
    return "sftp://" + username + ":" + password + "@" + hostName + "/"
        + remoteFilePath;
  }

  public static FileSystemOptions createDefaultOptions()
      throws FileSystemException {
    // Create SFTP options
    FileSystemOptions opts = new FileSystemOptions();

    // SSH Key checking
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
        opts, "no");

    // Root directory set to user home
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);

    // Timeout is count by Milliseconds
    SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);

    return opts;
  }

}