【发布时间】:2015-04-28 22:20:40
【问题描述】:
最近在 Ganymed SSH2 库中更改了 SCP 的实现。我正在努力弄清楚如何将文件推送到服务器。 SCPOutputStream 类似乎不接受实际文件,只是文件名和远程路径。有人可以帮我理解如何实现它来推送文件吗?请注意,我使用的是最新版本的 Ganymede。
谢谢!
【问题讨论】:
最近在 Ganymed SSH2 库中更改了 SCP 的实现。我正在努力弄清楚如何将文件推送到服务器。 SCPOutputStream 类似乎不接受实际文件,只是文件名和远程路径。有人可以帮我理解如何实现它来推送文件吗?请注意,我使用的是最新版本的 Ganymede。
谢谢!
【问题讨论】:
不要将其视为将本地文件复制到远程系统。将其视为在远程系统上写入文件,其内容可能来自本地文件,也可能不来自本地文件。
SCPClient.put() 启动将文件写入远程系统的过程。您指定远程文件的名称、放置它的远程目录、文件大小和文件的模式(权限)。所有这些都是 SCP 协议所要求的。
SCPOutputStream 是您用来写入远程文件的对象。写入流的任何内容都会发送到远程系统并保存在远程文件中。完成写入后关闭流。
要将本地文件复制到远程系统,您需要获取本地文件的名称和大小,并确定您想要的模式(您可以使用 0644 或 0666 作为模式)。然后调用SCPClient.put() 开始写入远程文件。 SCPClient.put() 返回一个 SCPOutputStream。您将打开本地文件进行读取并将其内容复制到SCPOutputStream。完成后关闭SCPOutputStream 和您用来从本地文件读取的流。
【讨论】:
可能对原始 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
【讨论】: