I'm trying to retrieve a file from a server using SFTP (as opposed to FTPS) using Java. How can I do this?
16 Answers
Another option is to consider looking at the JSch library. JSch seems to be the preferred library for a few large open source projects, including Eclipse, Ant and Apache Commons HttpClient, amongst others.
It supports both user/pass and certificate-based logins nicely, as well as all a whole host of other yummy SSH2 features.
Here's a simple remote file retrieve over SFTP. Error handling is left as an exercise for the reader :-)
JSch jsch = new JSch();
String knownHostsFilename = "/home/username/.ssh/known_hosts";
jsch.setKnownHosts( knownHostsFilename );
Session session = jsch.getSession( "remote-username", "remote-host" );
{
// "interactive" version
// can selectively update specified known_hosts file
// need to implement UserInfo interface
// MyUserInfo is a swing implementation provided in
// examples/Sftp.java in the JSch dist
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
// OR non-interactive version. Relies in host key being in known-hosts file
session.setPassword( "remote-password" );
}
session.connect();
Channel channel = session.openChannel( "sftp" );
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.get("remote-file", "local-file" );
// OR
InputStream in = sftpChannel.get( "remote-file" );
// process inputstream as needed
sftpChannel.exit();
session.disconnect();

- 35,194
- 20
- 73
- 86
-
1Cheekysoft, I noticed - while using Jsch - removing files on the sftp-server does not work. Also renaming files does not work too. Any ideas please??? Andy – Jan 31 '11 at 01:24
-
1Sorry, it is not something i work with at the moment. (Please try and leave these sort of responses as comments -- like this message -- and not as a new answer to the original question) – Cheekysoft Jan 31 '11 at 01:24
-
1What is that code block after the assignment of session? Is that some fancy Java syntax I've never seen? If so - what does it accomplish being written that way? – Michael Peterson Oct 17 '14 at 14:19
-
4@p1x3l5 standard java syntax allows a block to be inserted anywhere; it can be used to provide finer control over variable scope, if you wish. However, in this case, it is just a visual aid to help indicate the two implementation choices: either use the interactive version which requests a password from the user, or use a hardcoded password requiring no user intervention but arguably an additional security risk. – Cheekysoft Nov 05 '14 at 10:37
-
Another example relying on JSch library : https://www.baeldung.com/java-file-sftp – Raymond Chenon Oct 20 '21 at 16:30
-
1@RaymondChenon Be aware that this example on Baeldung does not appear to close the session after the transfer which could cause issues on the server side. You would probably want to call `channelSftp.getSession().disconnect()` after `channelSftp.exit()`. – Robert Hunt Aug 12 '22 at 08:07
-
1JSch hasn't been updated since 2018. Is this still the best answer in 2023? – Edward Mar 28 '23 at 23:44
Here is the complete source code of an example using JSch without having to worry about the ssh key checking.
import com.jcraft.jsch.*;
public class TestJSch {
public static void main(String args[]) {
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("username", "127.0.0.1", 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("password");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.get("remotefile.txt", "localfile.txt");
sftpChannel.exit();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
}

- 2,762
- 1
- 24
- 31
-
18A `finally` block should be used to include the channel clean-up code, to ensure that it always runs. – hotshot309 Nov 18 '13 at 17:47
-
I'm getting this exception now: ```com.jcraft.jsch.JSchException: Session.connect: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 2048 (inclusive)``` – fIwJlxSzApHEZIl Jan 19 '16 at 19:07
-
I found JSCH to have 0 or 1 extra dependencies. You can ignore the JZLIB dependency if you disable compression. // disable compression session.setConfig("compression.s2c", "none"); session.setConfig("compression.c2s", "none"); – englebart Feb 01 '19 at 19:19
-
1Without strict host checking you're susceptible to a man-in-the-middle attack. – rustyx Mar 13 '19 at 14:16
Below is an example using Apache Common VFS:
FileSystemOptions fsOptions = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");
FileSystemManager fsManager = VFS.getManager();
String uri = "sftp://user:password@host:port/absolute-path";
FileObject fo = fsManager.resolveFile(uri, fsOptions);

- 9,164
- 7
- 40
- 39
-
9Another nice thing to do is to set the timeout, so that if the remote system is offline, you don't hang there forever. You can do this just like was done for the host key check disable: SftpFileSystemConfigBuilder.getInstance().setTimeout(fsOptions, 5000); – Scott Jones Sep 06 '12 at 13:35
-
How would you advise close this connection when using multiple SFTP clients at the same time ? – 2Big2BeSmall Aug 07 '16 at 06:23
-
2
A nice abstraction on top of Jsch is Apache commons-vfs which offers a virtual filesystem API that makes accessing and writing SFTP files almost transparent. Worked well for us.

- 10,858
- 8
- 45
- 59
-
1is it possible to use pre-shared keys in combination with commons-vfs? – Benedikt Waldvogel May 15 '09 at 13:46
-
2Yes it is. If you need non-standard identities you can call SftpFileSystemConfigBuilder.getInstance().setIdentities(...). – Russ Hayward Jan 27 '11 at 11:05
-
You can use pre-shared keys. But this keys have to be without password. OtrosLogViewer is using SSH key authorization with VFS but requires to remove passphrase from key (http://code.google.com/p/otroslogviewer/wiki/SftpAuthPubKey) – KrzyH Dec 18 '12 at 13:05
-
I must say, that library is reallt overhead for the question requirements. the part that handles sftp is something like 10% of the library or even less... – Itay wazana Jun 02 '21 at 09:42
This was the solution I came up with http://sourceforge.net/projects/sshtools/ (most error handling omitted for clarity). This is an excerpt from my blog
SshClient ssh = new SshClient();
ssh.connect(host, port);
//Authenticate
PasswordAuthenticationClient passwordAuthenticationClient = new PasswordAuthenticationClient();
passwordAuthenticationClient.setUsername(userName);
passwordAuthenticationClient.setPassword(password);
int result = ssh.authenticate(passwordAuthenticationClient);
if(result != AuthenticationProtocolState.COMPLETE){
throw new SFTPException("Login to " + host + ":" + port + " " + userName + "/" + password + " failed");
}
//Open the SFTP channel
SftpClient client = ssh.openSftpClient();
//Send the file
client.put(filePath);
//disconnect
client.quit();
ssh.disconnect();

- 7,402
- 14
- 50
- 62
-
8I agree (belatedly), it worked fine for the original site/download I required but it refuesed to work for the new one. I'm in the process of switching to JSch – David Hayes Jan 27 '11 at 14:09
There is a nice comparison of the 3 mature Java libraries for SFTP: Commons VFS, SSHJ and JSch
To sum up SSHJ has the clearest API and it's the best out of them if you don't need other storages support provided by Commons VFS.
Here is edited SSHJ example from github:
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts(); // or, to skip host verification: ssh.addHostKeyVerifier(new PromiscuousVerifier())
ssh.connect("localhost");
try {
ssh.authPassword("user", "password"); // or ssh.authPublickey(System.getProperty("user.name"))
final SFTPClient sftp = ssh.newSFTPClient();
try {
sftp.get("test_file", "/tmp/test.tmp");
} finally {
sftp.close();
}
} finally {
ssh.disconnect();
}

- 1,393
- 16
- 17
-
2
-
2sshj in 2019 is still well maintained and is used by Alpakka (Akka) project – Maxence Jan 24 '19 at 14:35
See http://www.mysamplecode.com/2013/06/sftp-apache-commons-file-download.html
Apache Commons SFTP library
Common java properties file for all the examples
serverAddress=111.222.333.444
userId=myUserId
password=myPassword
remoteDirectory=products/
localDirectory=import/
Upload file to remote server using SFTP
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
public class SendMyFiles {
static Properties props;
public static void main(String[] args) {
SendMyFiles sendMyFiles = new SendMyFiles();
if (args.length < 1)
{
System.err.println("Usage: java " + sendMyFiles.getClass().getName()+
" Properties_file File_To_FTP ");
System.exit(1);
}
String propertiesFile = args[0].trim();
String fileToFTP = args[1].trim();
sendMyFiles.startFTP(propertiesFile, fileToFTP);
}
public boolean startFTP(String propertiesFilename, String fileToFTP){
props = new Properties();
StandardFileSystemManager manager = new StandardFileSystemManager();
try {
props.load(new FileInputStream("properties/" + propertiesFilename));
String serverAddress = props.getProperty("serverAddress").trim();
String userId = props.getProperty("userId").trim();
String password = props.getProperty("password").trim();
String remoteDirectory = props.getProperty("remoteDirectory").trim();
String localDirectory = props.getProperty("localDirectory").trim();
//check if the file exists
String filepath = localDirectory + fileToFTP;
File file = new File(filepath);
if (!file.exists())
throw new RuntimeException("Error. Local file not found");
//Initializes the file manager
manager.init();
//Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
//Create the SFTP URI using the host name, userid, password, remote path and file name
String sftpUri = "sftp://" + userId + ":" + password + "@" + serverAddress + "/" +
remoteDirectory + fileToFTP;
// Create local file object
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
// Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
System.out.println("File upload successful");
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
finally {
manager.close();
}
return true;
}
}
Download file from remote server using SFTP
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
public class GetMyFiles {
static Properties props;
public static void main(String[] args) {
GetMyFiles getMyFiles = new GetMyFiles();
if (args.length < 1)
{
System.err.println("Usage: java " + getMyFiles.getClass().getName()+
" Properties_filename File_To_Download ");
System.exit(1);
}
String propertiesFilename = args[0].trim();
String fileToDownload = args[1].trim();
getMyFiles.startFTP(propertiesFilename, fileToDownload);
}
public boolean startFTP(String propertiesFilename, String fileToDownload){
props = new Properties();
StandardFileSystemManager manager = new StandardFileSystemManager();
try {
props.load(new FileInputStream("properties/" + propertiesFilename));
String serverAddress = props.getProperty("serverAddress").trim();
String userId = props.getProperty("userId").trim();
String password = props.getProperty("password").trim();
String remoteDirectory = props.getProperty("remoteDirectory").trim();
String localDirectory = props.getProperty("localDirectory").trim();
//Initializes the file manager
manager.init();
//Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
//Create the SFTP URI using the host name, userid, password, remote path and file name
String sftpUri = "sftp://" + userId + ":" + password + "@" + serverAddress + "/" +
remoteDirectory + fileToDownload;
// Create local file object
String filepath = localDirectory + fileToDownload;
File file = new File(filepath);
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
// Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
// Copy local file to sftp server
localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);
System.out.println("File download successful");
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
finally {
manager.close();
}
return true;
}
}
Delete a file on remote server using SFTP
import java.io.FileInputStream;
import java.util.Properties;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
public class DeleteRemoteFile {
static Properties props;
public static void main(String[] args) {
DeleteRemoteFile getMyFiles = new DeleteRemoteFile();
if (args.length < 1)
{
System.err.println("Usage: java " + getMyFiles.getClass().getName()+
" Properties_filename File_To_Delete ");
System.exit(1);
}
String propertiesFilename = args[0].trim();
String fileToDownload = args[1].trim();
getMyFiles.startFTP(propertiesFilename, fileToDownload);
}
public boolean startFTP(String propertiesFilename, String fileToDownload){
props = new Properties();
StandardFileSystemManager manager = new StandardFileSystemManager();
try {
props.load(new FileInputStream("properties/" + propertiesFilename));
String serverAddress = props.getProperty("serverAddress").trim();
String userId = props.getProperty("userId").trim();
String password = props.getProperty("password").trim();
String remoteDirectory = props.getProperty("remoteDirectory").trim();
//Initializes the file manager
manager.init();
//Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
//Create the SFTP URI using the host name, userid, password, remote path and file name
String sftpUri = "sftp://" + userId + ":" + password + "@" + serverAddress + "/" +
remoteDirectory + fileToDownload;
//Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
//Check if the file exists
if(remoteFile.exists()){
remoteFile.delete();
System.out.println("File delete successful");
}
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
finally {
manager.close();
}
return true;
}
}

- 4,555
- 31
- 31
- 45

- 21,688
- 25
- 143
- 191
-
how to configure while having ssh-key (public key) to copy files on server. Because i need to make ssh_trust between my server and remote server. – M S Parmar Aug 14 '15 at 12:37
hierynomus/sshj has a complete implementation of SFTP version 3 (what OpenSSH implements)
Example code from SFTPUpload.java
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.xfer.FileSystemFile;
import java.io.File;
import java.io.IOException;
/** This example demonstrates uploading of a file over SFTP to the SSH server. */
public class SFTPUpload {
public static void main(String[] args)
throws IOException {
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("localhost");
try {
ssh.authPublickey(System.getProperty("user.name"));
final String src = System.getProperty("user.home") + File.separator + "test_file";
final SFTPClient sftp = ssh.newSFTPClient();
try {
sftp.put(new FileSystemFile(src), "/tmp");
} finally {
sftp.close();
}
} finally {
ssh.disconnect();
}
}
}
JSch library is the powerful library that can be used to read file from SFTP server. Below is the tested code to read file from SFTP location line by line
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("user", "127.0.0.1", 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("password");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
InputStream stream = sftpChannel.get("/usr/home/testfile.txt");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException io) {
System.out.println("Exception occurred during reading file from SFTP server due to " + io.getMessage());
io.getMessage();
} catch (Exception e) {
System.out.println("Exception occurred during reading file from SFTP server due to " + e.getMessage());
e.getMessage();
}
sftpChannel.exit();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
Please refer the blog for whole program.

- 963
- 3
- 14
- 21
Andy, to delete file on remote system you need to use (channelExec)
of JSch and pass unix/linux commands to delete it.

- 5,941
- 6
- 31
- 46

- 172
- 2
- 10
Though answers above were very helpful, I've spent a day to make them work, facing various exceptions like "broken channel", "rsa key unknown" and "packet corrupt".
Below is a working reusable class for SFTP FILES UPLOAD/DOWNLOAD using JSch library.
Upload usage:
SFTPFileCopy upload = new SFTPFileCopy(true, /path/to/sourcefile.png", /path/to/destinationfile.png");
Download usage:
SFTPFileCopy download = new SFTPFileCopy(false, "/path/to/sourcefile.png", "/path/to/destinationfile.png");
The class code:
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JOptionPane;
import menue.Menue;
public class SFTPFileCopy1 {
public SFTPFileCopy1(boolean upload, String sourcePath, String destPath) throws FileNotFoundException, IOException {
Session session = null;
Channel channel = null;
ChannelSftp sftpChannel = null;
try {
JSch jsch = new JSch();
//jsch.setKnownHosts("/home/user/.putty/sshhostkeys");
session = jsch.getSession("login", "mysite.com", 22);
session.setPassword("password");
UserInfo ui = new MyUserInfo() {
public void showMessage(String message) {
JOptionPane.showMessageDialog(null, message);
}
public boolean promptYesNo(String message) {
Object[] options = {"yes", "no"};
int foo = JOptionPane.showOptionDialog(null,
message,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
return foo == 0;
}
};
session.setUserInfo(ui);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channel = session.openChannel("sftp");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
sftpChannel = (ChannelSftp) channel;
if (upload) { // File upload.
byte[] bufr = new byte[(int) new File(sourcePath).length()];
FileInputStream fis = new FileInputStream(new File(sourcePath));
fis.read(bufr);
ByteArrayInputStream fileStream = new ByteArrayInputStream(bufr);
sftpChannel.put(fileStream, destPath);
fileStream.close();
} else { // File download.
byte[] buffer = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(sftpChannel.get(sourcePath));
OutputStream os = new FileOutputStream(new File(destPath));
BufferedOutputStream bos = new BufferedOutputStream(os);
int readCount;
while ((readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
}
bis.close();
bos.close();
}
} catch (Exception e) {
System.out.println(e);
} finally {
if (sftpChannel != null) {
sftpChannel.exit();
}
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
public static abstract class MyUserInfo
implements UserInfo, UIKeyboardInteractive {
public String getPassword() {
return null;
}
public boolean promptYesNo(String str) {
return false;
}
public String getPassphrase() {
return null;
}
public boolean promptPassphrase(String message) {
return false;
}
public boolean promptPassword(String message) {
return false;
}
public void showMessage(String message) {
}
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo) {
return null;
}
}
}

- 18,610
- 7
- 91
- 99
I found complete working example for SFTP in java using JSCH API http://kodehelp.com/java-program-for-uploading-file-to-sftp-server/

- 29
- 3
Try edtFTPj/PRO, a mature, robust SFTP client library that supports connection pools and asynchronous operations. Also supports FTP and FTPS so all bases for secure file transfer are covered.

- 986
- 1
- 7
- 10
I use this SFTP API called Zehon, it's great, so easy to use with a lot of sample code. Here is the site http://www.zehon.com
-
2Zehon seems dead. And where's the source? What 'license' is behind 'free'? – rü- Oct 06 '15 at 15:00
You also have JFileUpload with SFTP add-on (Java too): http://www.jfileupload.com/products/sftp/index.html
-
JFileUpload is an applet, not a lib. License is commercial. Doesn't look active, either. – rü- Oct 06 '15 at 15:06
The best solution I've found is Paramiko. There's a Java version.

- 25,705
- 7
- 65
- 65
-
2https://github.com/terencehonles/jaramiko is abandoned in favor of JSch (see notice on github). – rü- Oct 06 '15 at 15:04