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