Запись данных буфера на SFTP-сервер с использованием Node и SSH2

Я пытаюсь реализовать запись файлов на SFTP-сервер в узле с помощью модуля SSH2. В моем случае источником файлов является хранилище BLOB-объектов Azure, а файлы относительно велики (более 5 гигабайт), поэтому идея состоит в том, чтобы собирать данные из хранилища BLOB-объектов по частям и записывать их на сервер. Не нужно загружать весь файл, а затем выполнять запись, так как файлы большие и не хотят иметь проблемы с дисковым пространством во время выполнения.

У меня есть рабочая реализация этого, используя доступные функции downloadToBuffer() и write() и увеличивая «смещение» до тех пор, пока все байты не будут записаны. Как видно из фрагмента кода

sftp.open('remoteFilePath','w', async (openError,handle) => {
  if (openError) throw openError;
  var blobOffset=0;
  try{
    while(blobOffset<file.size){
      await client.downloadToBuffer(blobOffset, blobOffset+ length > file.size? file.size - blobOffset: length).then((buffer) => {
        sftp.write(handle,buffer,0,blobOffset + length > file.size? buffer.length:length, blobOffset, (writeError)=>{if(writeError) throw writeError});
      });
      blobOffset += length;
    }
  }
  catch(e){
    console.log(e);
  }
}

Это решение работает, но не очень эффективно для больших файлов. Есть ли лучший способ реализовать это? Может быть, использовать потоки и не использовать циклы?


person yohaansunnie    schedule 25.01.2021    source источник


Ответы (1)


Что касается проблемы, пожалуйста, обратитесь к следующему коду

var Client = require("ssh2").Client;
var {
  BlobServiceClient,
  StorageSharedKeyCredential,
} = require("@azure/storage-blob");

var accountName = "andyprivate";
  var accountKey =
    "";
  var creds = new StorageSharedKeyCredential(accountName, accountKey);
  var blobServiceClient = new BlobServiceClient(
    `https://${accountName}.blob.core.windows.net`,
    creds
  );
  var containerClient = blobServiceClient.getContainerClient("output");
  let blob = containerClient.getBlockBlobClient("5m Sales Records.csv");
  let read = (await blob.download(0)).readableStreamBody;
  var conn = new Client();

  conn.connect({
    host: "",
    port: 22,
    username: "",
    password: "!",
  });

  conn.on("ready", async () => {
    conn.sftp((err, sftp) => {
      if (err) throw err;
      var write = sftp.createWriteStream("/home/testqw/test.csv");

      read.pipe(write);
      write
        .on("error", function (error) {
          throw error;
        })
        .on("finish", () => {
          console.log("All writes are now complete.");
          sftp.end();
        });
    });
  });
  conn.on("end", () => {
    console.log("close the connection");
  });
person Jim Xu    schedule 26.01.2021