How do I copy a directory using Ganymed's SCPClient?
I need to recursively copy a directory (C:\test in this case) to a remote host. I tried the obvious:
conn.connect();
conn.authenticateWithPassword("user", "pw");
SCPClient scp = conn.createSCPClient();
scp.put("C:/test", "~/test");
conn.close();
but this gives the error:
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.e开发者_如何学运维thz.ssh2.SCPClient.sendFiles(SCPClient.java:190)
at ch.ethz.ssh2.SCPClient.put(SCPClient.java:573)
... 3 more
Am I missing something, or can Ganymed really only copy individual files, but not directories? Should I just exec()
the appropriate scp command on the shell?
After digging up the relevant parts of the souce code, I'm fairly certain the answer is "you don't".
All the put()
methods that take one or more file names as parameters eventually call a private sendFiles()
method to actually send the files. This method creates a File
object from each filename, and then a FileInputStream
object from each file. And sure enough, FileInputStream
's constructor throws a FileNotFoundException
"if the file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading." (And, apparently, it doesn't always throw it with the correct error message.)
EDIT: Though in all fairness, it's not at all hard to roll your own recursive function that copies a directory:
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);
}
}
}
精彩评论