How to retrieve a file from a server via SFTP?

420,179

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();
Share:
420,179

Related videos on Youtube

David Hayes
Author by

David Hayes

Expert .NET developer with broad experience in Java and other languages/platforms

Updated on October 04, 2020

Comments

  • David Hayes
    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
    Benedikt Waldvogel about 15 years
    is it possible to use pre-shared keys in combination with commons-vfs?
  • Russ Hayward
    Russ Hayward over 13 years
    Yes it is. If you need non-standard identities you can call SftpFileSystemConfigBuilder.getInstance().setIdentities(...)‌​.
  • David Hayes
    David Hayes over 13 years
    I 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
    Cheekysoft over 13 years
    Sorry, 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
    Admin over 13 years
    Cheekysoft, 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
    Scott Jones over 11 years
    Another 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(fsOptio‌​ns, 5000);
  • KrzyH
    KrzyH over 11 years
    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 (code.google.com/p/otroslogviewer/wiki/SftpAuthPubKey)
  • AZ_
    AZ_ over 10 years
  • hotshot309
    hotshot309 over 10 years
    A finally block should be used to include the channel clean-up code, to ensure that it always runs.
  • Michael Peterson
    Michael Peterson over 9 years
    What 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
    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
    OhadR about 9 years
    nice job!! an example in the main page could be helpful though.
  • M S Parmar
    M S Parmar almost 9 years
    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.
  • rü-
    rü- over 8 years
    Zehon seems dead. And where's the source? What 'license' is behind 'free'?
  • rü-
    rü- over 8 years
    github.com/terencehonles/jaramiko is abandoned in favor of JSch (see notice on github).
  • rü-
    rü- over 8 years
    JFileUpload is an applet, not a lib. License is commercial. Doesn't look active, either.
  • fIwJlxSzApHEZIl
    fIwJlxSzApHEZIl over 8 years
    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)
  • 2Big2BeSmall
    2Big2BeSmall almost 8 years
    How would you advise close this connection when using multiple SFTP clients at the same time ?
  • User3
    User3 almost 7 years
    What if my password contains @ symbol?
  • Johan
    Johan over 5 years
    Is there a way to get the file as an InputStream?
  • Maxence
    Maxence over 5 years
    sshj in 2019 is still well maintained and is used by Alpakka (Akka) project
  • englebart
    englebart over 5 years
    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");
  • rustyx
    rustyx about 5 years
    Without strict host checking you're susceptible to a man-in-the-middle attack.
  • Itay wazana
    Itay wazana almost 3 years
    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...
  • Raymond Chenon
    Raymond Chenon over 2 years
    Another example relying on JSch library : baeldung.com/java-file-sftp