2008-10-14 30 views
66

¿Cuál es el mejor método para realizar una transferencia de 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 castillo hinchable. Ninguna de estas soluciones parece tener una respuesta fácil.scp via java

+2

Se puede romper hacia abajo los problemas que tiene con las distintas bibliotecas, ¿por qué no funcionan para usted? –

Respuesta

50

Terminé usando Jsch - era bastante sencillo, y parecía escalar bastante bien (cogía unos pocos miles de archivos cada pocos minutos).

+0

jsch resultó ser la mejor alternativa, pero la documentación es horrible. La sugerencia de Abarax para observar la tarea de hormigas scp fue muy útil. Realmente no está claro si el proyecto sigue siendo muy activo. Gracias por el consejo. –

+23

@LloydMeinholz: escribí [Javadocs] (http://epaul.github.com/jsch-documentation/simple.javadoc/) para esta biblioteca. –

+0

Paulo: ¡excelente trabajo! Se ven realmente útiles. –

2

El openssh project enumera varias alternativas de Java, Trilead SSH for Java parece ajustarse a lo que está solicitando.

+0

Trilead parece mucho más maduro que Jsch, pero carecía de soporte para sftp y scp, que es lo que buscaba.Actualmente, sftp solo admite get y put (necesito ls y rm también) y el soporte de scp se incluyó en la lista de experiencias. –

16

Tome una mirada here

Ese es el código fuente de la tarea SCP hormigas. El código en el método "ejecutar" es donde están las tuercas y los pernos de él. Esto debería darle una buena idea de lo que se requiere. Utiliza JSch, creo.

Alternativamente, también podría ejecutar directamente esta tarea Ant desde su código java.

2

Uso esta API de SFTP que tiene un SCP llamado 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

17

plug: ¡sshj es la única opción correcta! Vea estos ejemplos para comenzar: download, upload.

+4

¿La única opción sana? –

+1

Fui con sshj a Jsch ya que tenía una interfaz mucho más simple. – Chris

+0

@shikhar Los enlaces de ejemplo están muertos, ¿puedes actualizar? – BillMan

5

envolví JSCH con algunos métodos de utilidad para que sea un poco más amable y lo llamó

JSCP

Disponible aquí: https://github.com/willwarren/jscp utilidad

SCP de alquitrán en una carpeta, la cremallera, y SCP se en algún lugar, luego descomprímelo.

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

incluye también clases útiles - Scp y Exec, y una TarAndGzip, que trabajan en más o menos la misma manera.

1

JSch es una buena biblioteca para trabajar. Tiene una respuesta bastante fácil para tu 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

2

Miré muchas de estas soluciones y no gusta a muchos de ellos. Sobre todo porque es un paso molesto tener que identificar a los hosts conocidos. Eso y JSCH están en un nivel ridículamente bajo en relación con el comando scp.

Encontré una biblioteca que no requiere esto, pero se incluye y se utiliza como una herramienta de línea de comandos.https://code.google.com/p/scp-java-client/

Miré a través del código fuente y descubrí cómo usarlo sin la línea de comando. Aquí está 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("[email protected]:/path/on/remote"); 
    scp.execute(); 

El mayor inconveniente es que no se trata de un acuerdo de recompra experto (que pude encontrar). Pero la facilidad de uso me lo merece.

1

jsCH me ha funcionado muy bien. 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 la desactivación de StrictHostKeyChecking. Aunque es 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 se recomienda

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

    } 
1

Al igual que algunos de los presentes, terminé escribiendo una envoltura alrededor de la biblioteca JSch.

Se llama manera-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(); 
4

Esto se solución de alto nivel, no hay necesidad de 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 encontrar el JAR hormiguero 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 tarro. Hoy en día, jsch-0.1.52.jar. También Agregue este JAR en su proyecto.

Ahora bien, ¿puede usar facilmente en código Java las clases de hormigas Scp para copiar archivos en la red o SSHExec de comandos en servidores SSH.

4) Código Ejemplo 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(); 
+0

Estoy intentando esto pero recibí un error si hay alguna solución, entonces comente ---> com.jcraft.jsch.JSchException: Session.connect: java.security.NoSuchAlgorithmException: Algoritmo DH no disponible –

+1

Si necesita una solución rápida esto funciona como mágico y mucho más simple que usar JSch directamente, gracias. –

0

necesito copiar la carpeta de forma recursiva, después de probar diferentes soluciones, finalmente terminan por ProcessBuilder + esperar/desove

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 %[email protected]%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(); 
}