Как скопировать каталог, используя SCPClient Ганимеда? - PullRequest
3 голосов
/ 14 июля 2011

Мне нужно рекурсивно скопировать каталог (в данном случае C: \) на удаленный хост. Я попробовал очевидное:

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() соответствующую команду scp на оболочке?

1 Ответ

3 голосов
/ 15 июля 2011

После того, как я выкопал соответствующие части кода соуса, я вполне уверен, что ответ - "нет".

Все методы 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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...