nodejs скачать файлы с sftp - PullRequest
0 голосов
/ 04 мая 2018

Мне нужно загрузить .txt.pgp файлы из sftp. Я пробовал npm ssh2, ssh2-sftp-client и node-ssh без какого-либо успеха.

Самый близкий к этому моменту список файлов в удаленной папке, используя sftp.readdir (ssh2) или sftp.list (ssh2-sftp-client).

Я пробовал pipe и fs.createWriteStream и sftp.fastGet, но на моем локальном компьютере нет сохраненных файлов.

const conn = new Client();
conn.on('ready', () => {
    console.log('Client :: ready');

    conn.sftp((err, sftp) => {
        if (err) throw err;

        sftp.readdir('out', (err, list) => {
            if (err) throw err;

            list.forEach(item => {
                console.log(item.filename);

                const fileName = item.filename;

                sftp.fastGet(fileName, fileName, {}, downloadError => {
                    if(downloadError) throw downloadError;

                    console.log("Succesfully uploaded");
                });
            })
            conn.end();
        });
    });
}).connect(config);

OR

const Client = require('ssh2-sftp-client');
const sftp = new Client();

sftp.connect(config).then(() => {
    return sftp.list('out');
})
.then(files => {
    // console.log(files);
    if (files.length > 0) {
        console.log('got list of files!');
    }

    files.map(file => {
        const fileName = file.name;

        sftp.get(fileName)
        .then(() => {
            fs.writeFile(fileName);
        }); 
    })
})
.then(() => {
    sftp.end();
}).catch((err) => {
    console.log(err);
});

1 Ответ

0 голосов
/ 02 ноября 2018

Что касается вашей первой попытки (с модулем ssh2), я вижу три проблемы:

  1. Вы вызываете conn.end() вне серии предыдущих асинхронных функций, что почти наверняка приводит к закрытию сеанса SSH до того, как вы закончили скачивать файлы.
  2. Вы не предоставляете функции sftp.fastGet() правильный путь к удаленному файлу. Ранее в коде вы вызывали sftp.readdir() с аргументом удаленного каталога 'out', который возвращает список файлов, относящихся к удаленному каталогу. (Суть в том, что вам необходимо добавить в удаленный каталог имя файла, чтобы создать правильный путь.)
  3. Вы не обрабатываете событие потока error, поэтому я подозреваю, что вы не получаете полезных сообщений об ошибках, помогающих устранять неполадки.

Попробуйте что-то вроде:

const Client = require('ssh2').Client;
const conn = new Client();    
const sshOpt = someFunctionThatPopulatesSshOptions();    
const remoteDir = 'out';

conn.on('ready', () => {
  conn.sftp((err, sftp) => {
    if (err) throw err;
    sftp.readdir(remoteDir, (err, list) => {
      if (err) throw err;
      let count = list.length;
      list.forEach(item => {
        let remoteFile = remoteDir + '/' + item.filename;
        let localFile = '/tmp/' + item.filename;
        console.log('Downloading ' + remoteFile);
        sftp.fastGet(remoteFile, localFile, (err) => {
          if (err) throw err;
          console.log('Downloaded to ' + localFile);
          count--;
          if (count <= 0) {
            conn.end();
          }
        });
      });
    });
  });
});
conn.on('error', (err) => {
  console.error('SSH connection stream problem');
  throw err;
});
conn.connect(sshOpt);

Это должно решить все проблемы, которые я упомянул. В частности:

  1. Мы используем переменную count, чтобы сеанс SSH был закрыт только после загрузки всех файлов. (Я знаю, что это не красиво.)
  2. Мы ожидаем remoteDir для всех наших удаленных загрузок файлов.
  3. Мы слушаем событие error в нашем потоке conn.
...