我需要以递归方式将目录(在本例中为C:\ test)复制到远程主机。我尝试了显而易见的事实:
conn.connect();
conn.authenticateWithPassword("user", "pw");
SCPClient scp = conn.createSCPClient();
scp.put("C:/test", "~/test");
conn.close();
但这会产生错误:
java.io.IOException: Error during SCP transfer.
at ch.ethz.ssh2.SCPClient.put(SCPClient.java:577)
at ch.ethz.ssh2.SCPClient.put(SCPClient.java:535)
at ch.ethz.ssh2.SCPClient.put(SCPClient.java:430)
at Test.Test.main(Test.java:57)
Caused by: java.io.FileNotFoundException: C:\test (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at ch.ethz.ssh2.SCPClient.sendFiles(SCPClient.java:190)
at ch.ethz.ssh2.SCPClient.put(SCPClient.java:573)
... 3 more
我错过了什么,或者Ganymed真的只能复制单个文件,而不是目录吗?我应该exec()
在shell上使用适当的scp命令吗?
答案 0 :(得分:3)
在挖掘了源代码的相关部分后,我相当肯定答案是“你没有”。
将一个或多个文件名作为参数的所有put()
方法最终都会调用私有sendFiles()
方法来实际发送文件。此方法从每个文件名创建一个File
对象,然后从每个文件创建一个FileInputStream
对象。当然,FileInputStream
的构造函数会抛出FileNotFoundException
“如果文件不存在,是目录而不是常规文件,或者由于某些其他原因不能开放阅读。“ (并且,显然,它并不总是使用正确的错误消息抛出它。)
编辑:虽然公平地说,复制目录并不是很难推出自己的递归函数:
private static void putDir(Connection conn, String localDirectory, String remoteTargetDirectory, String mode) throws IOException {
final String[] fileList = curDir.list();
for (String file : fileList) {
final String fullFileName = localDirectory + "/" + file;
if (new File(fullFileName).isDirectory()) {
final String subDir = remoteTargetDirectory + "/" + file;
Session sess = conn.openSession();
sess.execCommand("mkdir " + subDir);
sess.waitForCondition(ChannelCondition.EOF, 0);
putDir(conn, fullFileName, subDir, mode);
}
else {
SCPClient scpc = conn.createSCPClient();
scpc.put(fullFileName, remoteTargetDirectory, mode);
}
}
}