¿Cómo recuperar un archivo de un servidor a través de SFTP?

Estoy tratando de recuperar un archivo de un servidor usando SFTP (a diferencia de FTPS) usando Java. ¿Cómo puedo hacer esto?

Otra opción es considerar mirar la biblioteca JSch . JSch parece ser la biblioteca preferida para algunos grandes proyectos de código abierto, incluidos Eclipse, Ant y Apache Commons HttpClient, entre otros.

Admite bien los inicios de sesión de usuarios / pases y certificados, así como todo un conjunto de otras funciones deliciosas de SSH2.

Aquí hay un archivo remoto simple que se recupera a través de SFTP. El manejo de errores se deja como un ejercicio para el lector 🙂

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(); 

Aquí está el código fuente completo de un ejemplo usando JSch sin tener que preocuparse por la verificación de la clave ssh.

 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(); } } } 

A continuación se muestra un ejemplo con 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); 

Esta fue la solución que se me ocurrió: http://sourceforge.net/projects/sshtools/ (la mayoría del manejo de errores se omite para mayor claridad). Este es un extracto de mi 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(); 

Una buena abstracción sobre Jsch es Apache commons-vfs que ofrece una API de sistema de archivos virtual que hace que el acceso y escritura de archivos SFTP sea casi transparente. Funcionó bien para nosotros

Hay una buena comparación de las 3 bibliotecas maduras de Java para SFTP: Commons VFS, SSHJ y JSch

Para resumir, SSHJ tiene la API más clara y es la mejor de ellas si no necesita otro soporte de almacenamiento proporcionado por Commons VFS.

Aquí está editado el ejemplo SSHJ de 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(); } 

Biblioteca Apache Commons SFTP

Archivo común de propiedades Java para todos los ejemplos

serverAddress = 111.222.333.444

userId = myUserId

password = myPassword

remoteDirectory = productos /

localDirectory = import /

Subir archivo al servidor remoto usando 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; } } 

Descargar archivo del servidor remoto usando 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; } } 

Eliminar un archivo en un servidor remoto usando 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; } } 

hierynomus / sshj tiene una implementación completa de SFTP versión 3 (lo que OpenSSH implementa)

Código de ejemplo de 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(); } } } 

La biblioteca JSch es la poderosa biblioteca que se puede usar para leer archivos del servidor SFTP. A continuación se muestra el código probado para leer el archivo de la ubicación de SFTP línea por línea

 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(); } 

Por favor, consulte el blog para todo el progtwig.

Andy, para eliminar el archivo en el sistema remoto necesita usar (channelExec) de JSch y pasar los comandos de unix / linux para eliminarlo.

Pruebe edtFTPj / PRO , una robusta biblioteca de cliente SFTP que admite grupos de conexiones y operaciones asincrónicas. También es compatible con FTP y FTPS, por lo que todas las bases para la transferencia segura de archivos están cubiertas.

Encontré un ejemplo de trabajo completo para SFTP en Java usando JSCH API http://kodehelp.com/java-program-for-uploading-file-to-sftp-server/

Aunque las respuestas anteriores fueron muy útiles, he pasado un día haciendo que funcionen, enfrentando varias excepciones como “canal roto”, “clave desconocida” y “paquete dañado”.

Debajo hay una clase reutilizable que funciona para los ARCHIVOS SFTP CARGAR / DESCARGAR utilizando la biblioteca JSch.

Cargar el uso:

 SFTPFileCopy upload = new SFTPFileCopy(true, /path/to/sourcefile.png", /path/to/destinationfile.png"); 

Uso de descarga:

 SFTPFileCopy download = new SFTPFileCopy(false, "/path/to/sourcefile.png", "/path/to/destinationfile.png"); 

El código de clase:

 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; } } } 

También tiene JFileUpload con complemento de SFTP (Java también): http://www.jfileupload.com/products/sftp/index.html

Uso esta API de SFTP llamada Zehon, es genial, muy fácil de usar y con un montón de código de muestra. Aquí está el sitio http://www.zehon.com

La mejor solución que he encontrado es Paramiko . Hay una versión de Java.