如何使用最新的Ganymed SSH2 SCP Implmentation将文件保存到服务器

时间:2014-06-11 14:29:03

标签: java ssh scp

最近,在Ganymed SSH2库中,SCP的实施发生了变化。我正在努力弄清楚如何将文件推送到服务器。 SCPOutputStream类似乎不接受实际文件只是文件名和远程路径。有人可以帮我理解如何实现这个来推送文件吗?请注意我使用的是最新版的Ganymede。

谢谢!

https://code.google.com/p/ganymed-ssh-2/source/browse/trunk/src/main/java/ch/ethz/ssh2/SCPClient.java

https://code.google.com/p/ganymed-ssh-2/source/browse/trunk/src/main/java/ch/ethz/ssh2/SCPOutputStream.java

2 个答案:

答案 0 :(得分:3)

不要将其视为将本地文件复制到远程系统。将其视为在远程系统上编写文件,其内容可能来自本地文件,也可能不来自本地文件。

SCPClient.put()启动将文件写入远程系统的过程。您可以指定远程文件的名称,要放入的远程目录,文件大小以及文件的模式(权限)。所有这些都是SCP协议所要求的。

SCPOutputStream是用于写入远程文件的对象。写入流的任何内容都将发送到远程系统并保存在远程文件中。完成写入后关闭流。

要将本地文件复制到远程系统,您将获得本地文件的名称和大小,并找出您想要的模式(您可以使用0644或0666作为模式)。然后调用SCPClient.put()开始写入远程文件。 SCPClient.put()会返回SCPOutputStream。您将打开本地文件进行读取,并将其内容复制到SCPOutputStream。完成后,关闭SCPOutputStream以及您用来从本地文件中读取的流。

答案 1 :(得分:0)

太晚可能对原始OP非常有用,但我最近解决了完全相同的问题。我也很努力,因为教程/示例显示了不同实现的解决方案。

问题是,方法scpclient.put实际上并没有将文件放在任何地方,它只是在远程服务器上打开一个特殊的输出流,您需要将原始本地文件输入,然后关闭所有内容。

这是我的Scala解决方案(可以通过添加分号和类型来转向Java),希望它可以帮助某人。

首先,我的SSHUtils类是一个包装器:

package foo
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader

import ch.ethz.ssh2.Connection
import ch.ethz.ssh2.Session
import ch.ethz.ssh2.StreamGobbler
import ch.ethz.ssh2.SCPClient
import ch.ethz.ssh2.SCPOutputStream

import org.apache.commons.io.IOUtils

case class ConnectionInfo(username:String, password:String,     hostname:String, port:Int)

object SSHUtils {

  def scp(src:String, size:Long, targetName:String,targetDir:String, ci:ConnectionInfo) : Unit = {
    val conn = connect(ci)
    val cli :SCPClient = conn.createSCPClient().asInstanceOf[SCPClient]
    val out :SCPOutputStream = cli.put(targetName, size, targetDir,"0644")
    val in = new  FileInputStream(new File(src))
    IOUtils.copy(in, out)
    in.close()
    out.close()
    conn.close()
  }

  def connect(ci: ConnectionInfo):Connection = {

    val conn = new Connection(ci.hostname, ci.port)
    conn.connect()
    val isAuthenticated = conn.authenticateWithPassword(ci.username, ci.password)
    if (isAuthenticated == false)
      throw new IOException("Authentication failed.")
    conn
  }
}

然后,我如何从我的scala控制台将一个小的txt文件复制到远程主机(在目录"。/"):

import foo.SSHUtils
import foo.ConnectionInfo
import java.io.File

val ci : ConnectionInfo = new ConnectionInfo(dc_username, dc_password, dc_host, dc_port)

val f = new File("/home/carolinux/qgis.txt")

SSHUtils.scp(f.toString, f.length,f.getName, "./", ci)

除了Ganymede库之外,我还需要使用commons.io来将本地文件写入scpoutputstream。 sbt依赖项是:

"commons-io" % "commons-io" % "2.4"
"ch.ethz.ganymed" % "ganymed-ssh2" % "262" // the latest one in maven at the time of writing