Загрузите несколько файлов в SFTP с узла

Я пытаюсь загрузить несколько файлов на свой SFTP-сервер, но мне не повезло. Я видел такой пример:

как отправить (положить) несколько файлов с помощью nodejs ssh2-sftp-client?

Но это не кажется очень эффективным методом, поскольку он открывает и закрывает соединение с сервером при каждой загрузке файла. Просто чтобы дать некоторый контекст, мое приложение потенциально могло бы попытаться загрузить многие тысячи файлов. Я отправляю массив имен файлов от клиента к серверу и вызываю SFTP.get, чтобы получить файл из удаленного места, и SFTP.put этот файловый поток обратно в другое удаленное место. Это делается с помощью модуля npm ssh2-sftp-client.

Я попытался загрузить несколько файлов, используя несколько разных методов, но безуспешно.

В первую очередь:

for (var i=0; i<10; i++) {

      sftp.get('filepath/testFile.csv').then((stream) => {
            sftp.put(stream, 'newfilepath/testFile' + i + '.csv');
      })

}

Это была просто попытка загрузить один и тот же файл по 10 раз каждый раз под другим именем. Однако когда я смотрю на свой сервер:

Загруженный файл

Был загружен только последний файл - при просмотре журналов он фактически пытался загрузить testFile10.csv 10 раз, а не testFile1.csv, testFile2.csv и т. Д.

Во-вторых:

var files = ['testFile.csv', 'testFile2.csv']

    for (var i=0; i<2; i++) {

        sftp.get('filepath/' + files[i]).then((stream) => {
            sftp.put(stream, 'newfilepath/testFile' + i + '.csv');
        })

    }

Это была попытка просто загрузить 2 файла. Однако, как и в предыдущем примере, был загружен только последний файл - в данном случае testFile2.csv.

Любые предложения, как я могу заставить это работать? Можно ли вообще ЗАГРУЗИТЬ несколько файлов в цикл for? Это не похоже на то, что должно быть технически сложным, я просто не понимаю, почему он даже не пытается зацикливаться от 0 до 10, он просто пытается поставить testFile10 10 раз.

Это довольно серьезное техническое препятствие, которое мне нужно преодолеть в срок, поэтому я буду очень признателен за любую помощь, которую вы можете оказать.

Спасибо заранее,

G


person GeorgeBT1902    schedule 27.11.2018    source источник


Ответы (1)


Поскольку асинхронный обратный вызов выполняется, когда обещание разрешено, вне основного порядка выполнения, когда он выполняется, i уже равен длине массива. Поэтому загружается только последний файл.

Таким образом, вы можете сделать это с помощью обещаний, например этого (я не могу сейчас это проверить):

const files = ['testFile.csv', 'testFile2.csv'];

const promises = files.map(async file => {
  const stream = await sftp.get(`filepath/${file}`);
  sftp.put(stream, file);
});

Promise.all(promises)
  .then(results => {
    console.log('all files have been uploaded');
    // do something
  })
  .catch(e => {
    console.error(e);
    // handle error
  });
person Vassilis Pallas    schedule 28.11.2018
comment
Эфхаристо Василис! Я попытался реализовать ваше второе предложение с помощью анонимной функции, но когда я его запустил, он снова загрузил только последний файл. Но ваше первое решение работает отлично! Вы избавили меня от огромной головной боли, решив эту проблему с помощью очень чистого решения, так что спасибо! - person GeorgeBT1902; 28.11.2018
comment
Я рада, что смогла помочь! - person Vassilis Pallas; 28.11.2018
comment
@VassilisPallas Когда я попробовал ваш код, он показал мне, что он есть. нет данных в файле. но на самом деле он содержит данные. Не могли бы вы мне помочь - person vijju; 11.05.2019