代码之家  ›  专栏  ›  技术社区  ›  Lloyd Meinholz

通过Java实现SCP

  •  70
  • Lloyd Meinholz  · 技术社区  · 17 年前

    通过Java编程语言执行SCP传输的最佳方法是什么?看来我可以通过JSSE、JSCH或Bosiy城堡Java库来执行这些操作。这些解决方案似乎都没有一个简单的答案。

    13 回复  |  直到 8 年前
        1
  •  51
  •   Stu Thompson Helter Scelter    14 年前

    我最后用了 Jsch -它非常简单,而且似乎扩展得很好(我每隔几分钟就要抓取几千个文件)。

        2
  •  19
  •   Julien Kronegg    9 年前

    插头:sshj是唯一理智的选择!请参阅以下示例开始: download , upload .

        3
  •  16
  •   abarax    17 年前

    看一看 here

    这是蚂蚁的scp任务的源代码。“执行”方法中的代码是它的螺母和螺栓所在的位置。这应该让您对所需内容有一个大致的了解。我相信它使用JSCH。

    或者,您也可以直接从Java代码执行此任务。

        4
  •  6
  •   Will    13 年前

    我用一些实用方法包装了JSCH,使其更友好,并将其命名为

    JSCP

    这里有: https://github.com/willwarren/jscp

    scp实用程序对文件夹进行tar、zip和scp,然后解压缩。

    用途:

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

    还包括有用的类——scp和exec,以及tarandgzip,它们的工作方式几乎相同。

        5
  •  4
  •   Fernando Santos    11 年前

    这是 高级解决方案 无需再创新。又快又脏!

    1) 首先,去 http://ant.apache.org/bindownload.cgi 下载最新的ApacheAnt二进制文件。(现在,apache-ant-1.9.4-bin.zip)。

    2) 提取下载的文件并找到jar 安达JJ (apache-ant-1.9.4/lib/ant jsch.jar)。 在项目中添加这个jar . 还有ant-launcher.jar和ant.jar。

    3) Jcraft jsch SouceForge Project 下载jar。如今, jsch-0.1.52.jar . 阿尔索 在项目中添加这个jar .

    现在,你能很容易地使用蚂蚁类的Java代码吗? 单链构象多态性 用于通过网络复制文件或 SSHEXEC 用于ssh服务器中的命令。

    4) 代码示例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();
    
        6
  •  2
  •   Kyle Burton    17 年前

    这个 openssh project 列出几种Java替代方案, Trilead SSH for Java 似乎符合你的要求。

        7
  •  2
  •   bigjavageek    17 年前

    我使用这个sftp api,它有一个叫做zehon的scp,非常好,很容易与许多示例代码一起使用。这是现场 http://www.zehon.com

        8
  •  2
  •   Daniel Kaplan    12 年前

    我看过很多这样的解决方案,但不喜欢其中的很多。主要是因为识别已知主机这一令人讨厌的步骤。与scp命令相比,jsch处于一个非常低的级别。

    我找到了一个不需要这个的库,但它被打包起来用作命令行工具。 https://code.google.com/p/scp-java-client/

    我浏览了源代码,发现了如何在没有命令行的情况下使用它。以下是上载示例:

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

    最大的缺点是它不在Maven回购协议中(我可以找到)。但是,易用性对我来说是值得的。

        9
  •  1
  •   user717263    12 年前

    像这里的一些人一样,我最终在JSCH库周围编写了一个包装器。

    它被称为way secshell,托管在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();
    
        10
  •  0
  •   boomz    13 年前

    我写了一个SCP服务器,比其他服务器容易得多。我使用apache mina项目(apache sshd)来开发它。你可以在这里看看: https://github.com/boomz/JSCP 您也可以从下载JAR文件 /jar 目录。 如何使用?看一看: https://github.com/boomz/JSCP/blob/master/src/Main.java

        11
  •  0
  •   Eddie Martinez    12 年前

    JSCH为我工作得很好。下面是一个将连接到sftp服务器并将文件下载到指定目录的方法示例。建议不要禁用严格的hostkeychecking。尽管设置起来有点困难,但是出于安全原因,指定已知主机应该是标准的。

    jsch.setknownhosts(“c:\users\test\known\u hosts”); 推荐

    jsch.setconfig(“stricthostkeychecking”,“no”); -不推荐

    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();
                }
            }
    
        }
    
        12
  •  0
  •   yole    11 年前

    JSCH是一个很好的库。这个问题的答案很简单。

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

    您可以在以下位置找到完整的代码:

    http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html

        13
  •  0
  •   Burt    8 年前

    我需要递归地复制文件夹,在尝试不同的解决方案后,最终由processbuilder+expect/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();
    }
    
    推荐文章