How to retrieve a file from a server via SFTP?
Solution 1
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();
Solution 2
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();
}
}
}
Solution 3
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);
Solution 4
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.
Solution 5
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();
Related videos on Youtube
David Hayes
Expert .NET developer with broad experience in Java and other languages/platforms
Updated on October 04, 2020Comments
-
David Hayes over 3 years
I'm trying to retrieve a file from a server using SFTP (as opposed to FTPS) using Java. How can I do this?
-
Benedikt Waldvogel about 15 yearsis it possible to use pre-shared keys in combination with commons-vfs?
-
Russ Hayward over 13 yearsYes it is. If you need non-standard identities you can call SftpFileSystemConfigBuilder.getInstance().setIdentities(...).
-
David Hayes over 13 yearsI 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
-
Cheekysoft over 13 yearsSorry, 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)
-
Admin over 13 yearsCheekysoft, 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
-
Scott Jones over 11 yearsAnother 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);
-
KrzyH over 11 yearsYou 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 (code.google.com/p/otroslogviewer/wiki/SftpAuthPubKey)
-
AZ_ over 10 years
-
hotshot309 over 10 yearsA
finally
block should be used to include the channel clean-up code, to ensure that it always runs. -
Michael Peterson over 9 yearsWhat 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?
-
Cheekysoft over 9 years@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.
-
OhadR about 9 yearsnice job!! an example in the main page could be helpful though.
-
M S Parmar almost 9 yearshow 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.
-
rü- over 8 yearsZehon seems dead. And where's the source? What 'license' is behind 'free'?
-
rü- over 8 yearsgithub.com/terencehonles/jaramiko is abandoned in favor of JSch (see notice on github).
-
rü- over 8 yearsJFileUpload is an applet, not a lib. License is commercial. Doesn't look active, either.
-
fIwJlxSzApHEZIl over 8 yearsI'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)
-
2Big2BeSmall almost 8 yearsHow would you advise close this connection when using multiple SFTP clients at the same time ?
-
User3 almost 7 yearsWhat if my password contains @ symbol?
-
Johan over 5 yearsIs there a way to get the file as an InputStream?
-
Maxence over 5 yearssshj in 2019 is still well maintained and is used by Alpakka (Akka) project
-
englebart over 5 yearsI 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");
-
rustyx about 5 yearsWithout strict host checking you're susceptible to a man-in-the-middle attack.
-
Itay wazana almost 3 yearsI 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...
-
Raymond Chenon over 2 yearsAnother example relying on JSch library : baeldung.com/java-file-sftp