¿Cuál es el mejor método para realizar una transferencia scp a través del lenguaje de programación Java? Parece que puedo realizar esto a través de JSSE, JSch o las bibliotecas java del castillo hinchable. Ninguna de estas soluciones parece tener una respuesta fácil.
81
Respuestas:
Terminé usando Jsch , era bastante sencillo y parecía escalar bastante bien (estaba tomando unos pocos miles de archivos cada pocos minutos).
fuente
enchufe: sshj es la única opción sensata. Vea estos ejemplos para comenzar: descargar , cargar .
fuente
Echa un vistazo aquí
Ese es el código fuente de la tarea SCP de Ants. El código en el método "ejecutar" es donde están las tuercas y tornillos. Esto debería darle una idea clara de lo que se requiere. Utiliza JSch, creo.
Alternativamente, también puede ejecutar directamente esta tarea Ant desde su código java.
fuente
Envolví Jsch con algunos métodos de utilidad para hacerlo un poco más amigable y lo llamé
Jscp
Disponible aquí: https://github.com/willwarren/jscp
Utilidad SCP para tar una carpeta, comprimirla y scp en alguna parte, luego descomprimirla.
Uso:
// create secure context SecureContext context = new SecureContext("userName", "localhost"); // set optional security configurations. context.setTrustAllHosts(true); context.setPrivateKeyFile(new File("private/key")); // Console requires JDK 1.7 // System.out.println("enter password:"); // context.setPassword(System.console().readPassword()); Jscp.exec(context, "src/dir", "destination/path", // regex ignore list Arrays.asList("logs/log[0-9]*.txt", "backups") );
También incluye clases útiles: Scp y Exec, y TarAndGzip, que funcionan prácticamente de la misma manera.
fuente
Esta es una solución de alto nivel , no es necesario reinventar. ¡Rápido y sucio!
1) Primero, vaya a http://ant.apache.org/bindownload.cgi y descargue el último binario de Apache Ant. (hoy en día, apache-ant-1.9.4-bin.zip).
2) Extraiga el archivo descargado y busque el JAR ant-jsch.jar ("apache-ant-1.9.4 / lib / ant-jsch.jar"). Agregue este JAR en su proyecto . También ant-launcher.jar y ant.jar.
3) Vaya a Jcraft jsch SouceForge Project y descargue el archivo jar. Hoy en día, jsch-0.1.52.jar . También agregue este JAR en su proyecto .
Ahora, ¿puedes usar fácilmente en código java las clases Ant Scp para copiar archivos a través de la red o SSHExec para comandos en servidores SSH?
4) Ejemplo de código Scp:
// This make scp copy of // one local file to remote dir org.apache.tools.ant.taskdefs.optional.ssh.Scp scp = new Scp(); int portSSH = 22; String srvrSSH = "ssh.your.domain"; String userSSH = "anyuser"; String pswdSSH = new String ( jPasswordField1.getPassword() ); String localFile = "C:\\localfile.txt"; String remoteDir = "/uploads/"; scp.setPort( portSSH ); scp.setLocalFile( localFile ); scp.setTodir( userSSH + ":" + pswdSSH + "@" + srvrSSH + ":" + remoteDir ); scp.setProject( new Project() ); scp.setTrust( true ); scp.execute();
fuente
El proyecto openssh enumera varias alternativas de Java, Trilead SSH para Java parece encajar con lo que está pidiendo.
fuente
Utilizo esta API SFTP que tiene SCP llamada Zehon, es genial, muy fácil de usar con una gran cantidad de código de muestra. Aquí está el sitio http://www.zehon.com
fuente
Miré muchas de estas soluciones y no me gustaron muchas de ellas. Principalmente debido al molesto paso de tener que identificar sus hosts conocidos. Eso y JSCH está en un nivel ridículamente bajo en relación con el comando scp.
Encontré una biblioteca que no requiere esto, pero está agrupada y se usa como una herramienta de línea de comandos. https://code.google.com/p/scp-java-client/
Revisé el código fuente y descubrí cómo usarlo sin la línea de comandos. Aquí hay un ejemplo de carga:
uk.co.marcoratto.scp.SCP scp = new uk.co.marcoratto.scp.SCP(new uk.co.marcoratto.scp.listeners.SCPListenerPrintStream()); scp.setUsername("root"); scp.setPassword("blah"); scp.setTrust(true); scp.setFromUri(file.getAbsolutePath()); scp.setToUri("root@host:/path/on/remote"); scp.execute();
El mayor inconveniente es que no está en un repositorio de maven (que pude encontrar). Pero, para mí, la facilidad de uso lo vale.
fuente
jsCH ha funcionado muy bien para mí. A continuación se muestra un ejemplo de un método que se conectará al servidor sftp y descargará archivos al directorio especificado. Se recomienda evitar desactivar StrictHostKeyChecking. Aunque un poco más difícil de configurar, por razones de seguridad, especificar los hosts conocidos debería ser la norma.
jsch.setKnownHosts ("C: \ Users \ test \ known_hosts"); recomendado
JSch.setConfig ("StrictHostKeyChecking", "no"); - no recomendado
import com.jcraft.jsch.*; public void downloadFtp(String userName, String password, String host, int port, String path) { Session session = null; Channel channel = null; try { JSch ssh = new JSch(); JSch.setConfig("StrictHostKeyChecking", "no"); session = ssh.getSession(userName, host, port); session.setPassword(password); session.connect(); channel = session.openChannel("sftp"); channel.connect(); ChannelSftp sftp = (ChannelSftp) channel; sftp.get(path, "specify path to where you want the files to be output"); } catch (JSchException e) { System.out.println(userName); e.printStackTrace(); } catch (SftpException e) { System.out.println(userName); e.printStackTrace(); } finally { if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } }
fuente
Como algunos aquí, terminé escribiendo un contenedor alrededor de la biblioteca JSch.
Se llama way-secshell y está alojado en GitHub:
https://github.com/objectos/way-secshell
// scp myfile.txt localhost:/tmp File file = new File("myfile.txt"); Scp res = WaySSH.scp() .file(file) .toHost("localhost") .at("/tmp") .send();
fuente
JSch es una buena biblioteca para trabajar. Tiene una respuesta bastante fácil para su pregunta.
JSch jsch=new JSch(); Session session=jsch.getSession(user, host, 22); session.setPassword("password"); Properties config = new Properties(); config.put("StrictHostKeyChecking","no"); session.setConfig(config); session.connect(); boolean ptimestamp = true; // exec 'scp -t rfile' remotely String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile; Channel channel=session.openChannel("exec"); ((ChannelExec)channel).setCommand(command); // get I/O streams for remote scp OutputStream out=channel.getOutputStream(); InputStream in=channel.getInputStream(); channel.connect(); if(checkAck(in)!=0){ System.exit(0); } File _lfile = new File(lfile); if(ptimestamp){ command="T "+(_lfile.lastModified()/1000)+" 0"; // The access time should be sent here, // but it is not accessible with JavaAPI ;-< command+=(" "+(_lfile.lastModified()/1000)+" 0\n"); out.write(command.getBytes()); out.flush(); if(checkAck(in)!=0){ System.exit(0); } }
Puede encontrar el código completo en
http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html
fuente
Aquí hay un ejemplo para cargar un archivo usando JSch :
ScpUploader.java
:import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; import java.io.ByteArrayInputStream; import java.util.Properties; public final class ScpUploader { public static ScpUploader newInstance() { return new ScpUploader(); } private volatile Session session; private volatile ChannelSftp channel; private ScpUploader(){} public synchronized void connect(String host, int port, String username, String password) throws JSchException { JSch jsch = new JSch(); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session = jsch.getSession(username, host, port); session.setPassword(password); session.setConfig(config); session.setInputStream(System.in); session.connect(); channel = (ChannelSftp) session.openChannel("sftp"); channel.connect(); } public synchronized void uploadFile(String directoryPath, String fileName, byte[] fileBytes, boolean overwrite) throws SftpException { if(session == null || channel == null) { System.err.println("No open session!"); return; } // a workaround to check if the directory exists. Otherwise, create it channel.cd("/"); String[] directories = directoryPath.split("/"); for(String directory : directories) { if(directory.length() > 0) { try { channel.cd(directory); } catch(SftpException e) { // swallowed exception System.out.println("The directory (" + directory + ") seems to be not exist. We will try to create it."); try { channel.mkdir(directory); channel.cd(directory); System.out.println("The directory (" + directory + ") is created successfully!"); } catch(SftpException e1) { System.err.println("The directory (" + directory + ") is failed to be created!"); e1.printStackTrace(); return; } } } } channel.put(new ByteArrayInputStream(fileBytes), directoryPath + "/" + fileName, overwrite ? ChannelSftp.OVERWRITE : ChannelSftp.RESUME); } public synchronized void disconnect() { if(session == null || channel == null) { System.err.println("No open session!"); return; } channel.exit(); channel.disconnect(); session.disconnect(); channel = null; session = null; } }
AppEntryPoint.java
:import com.jcraft.jsch.JSchException; import com.jcraft.jsch.SftpException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public final class AppEntryPoint { private static final String HOST = "192.168.1.1"; private static final int PORT = 22; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; public static void main(String[] args) throws IOException { ScpUploader scpUploader = ScpUploader.newInstance(); try { scpUploader.connect(HOST, PORT, USERNAME, PASSWORD); } catch(JSchException e) { System.err.println("Failed to connect the server!"); e.printStackTrace(); return; } System.out.println("Successfully connected to the server!"); byte[] fileBytes = Files.readAllBytes(Paths.get("C:/file.zip")); try { scpUploader.uploadFile("/test/files", "file.zip", fileBytes, true); // if overwrite == false, it won't throw exception if the file exists System.out.println("Successfully uploaded the file!"); } catch(SftpException e) { System.err.println("Failed to upload the file!"); e.printStackTrace(); } scpUploader.disconnect(); } }
fuente
Escribí un servidor scp que es mucho más fácil que otros. Utilizo el proyecto Apache MINA (Apache SSHD) para desarrollarlo. Puede echar un vistazo aquí: https://github.com/boomz/JSCP También puede descargar el archivo jar desde el
/jar
directorio. ¿Cómo utilizar? Eche un vistazo a: https://github.com/boomz/JSCP/blob/master/src/Main.javafuente
Necesito copiar la carpeta de forma recursiva, después de probar diferentes soluciones, finalmente termino con ProcessBuilder + wait / spawn
scpFile("192.168.1.1", "root","password","/tmp/1","/tmp"); public void scpFile(String host, String username, String password, String src, String dest) throws Exception { String[] scpCmd = new String[]{"expect", "-c", String.format("spawn scp -r %s %s@%s:%s\n", src, username, host, dest) + "expect \"?assword:\"\n" + String.format("send \"%s\\r\"\n", password) + "expect eof"}; ProcessBuilder pb = new ProcessBuilder(scpCmd); System.out.println("Run shell command: " + Arrays.toString(scpCmd)); Process process = pb.start(); int errCode = process.waitFor(); System.out.println("Echo command executed, any errors? " + (errCode == 0 ? "No" : "Yes")); System.out.println("Echo Output:\n" + output(process.getInputStream())); if(errCode != 0) throw new Exception(); }
fuente
-: Refinando un poco la respuesta de Fernando, si usa Maven para la gestión de dependencias: -
pom.xml :
Agregue esta dependencia en su proyecto. La última versión se puede encontrar aquí .
Código Java :
public void scpUpload(String source, String destination) { Scp scp = new Scp(); scp.setPort(port); scp.setLocalFile(source); scp.setTodir(username + ":" + password + "@" + host + ":" + destination); scp.setProject(new Project()); scp.setTrust(true); scp.execute(); }
fuente