Передача данных из Записываемого в Читаемый - PullRequest
0 голосов
/ 07 февраля 2020

Я работаю над получением файлов с SFTP-сервера и передачей данных на Box.com, используя их SDK. Box sdk принимает читаемый поток в качестве параметра для загрузки файла. Код, который я написал для извлечения файлов с сервера sftp, использует модуль npm ssh2-sftp-client.

У меня проблема в том, что записываемый поток - это «конец строки» с потоками если вы не используете что-то вроде Transform, который является дуплексом и реализует как чтение, так и запись. Ниже приведен код, который я использую. Поскольку я работаю над этим для клиента, я намеренно пропускаю некоторые ненужные вещи.

Ниже приведен метод класса sftp

async getFile(filepath: string): Promise<Readable> {
  logger.info(`Fetching file: ${filepath}`);
  const writable = new Writable();
  const stream = new PassThrough();
  await this.client.get(filepath, writable);
  return writable.pipe(stream);
}

Реализация получения файла и пытается передать по каналу, который является экземпляром авторизованного клиента BoxSDK.

try {
  for (const filename of filenames) {
    const stream: Readable = await tmsClient.getFile(
      'redacted' + filename,
    );

    logger.info(`Piping ${filename} to Box...`);
    await box.createFile(filename, 'redacted', stream);
    logger.info(`${filename} successfully downloaded`);
  }
} catch (error) {
  logger.error(`Failed to move files: ${error}`);
}

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

Я также пробовал эту реализацию, где клиент s sh возвращает буфер, а затем я пытаюсь передать этот буфер в виде читаемого потока. В этой реализации я продолжаю получать сообщения от SDK Box о том, что поток неожиданно завершился.

async getFile(filepath: string): Promise<Readable> {
  logger.info(`Fetching file: ${filepath}`);
  const stream = new Readable();
  const buffer = (await this.client.get(filepath)) as Buffer;
  stream._read = (): void => {
    stream.push(buffer);
    stream.push(null);
  };
  return stream;
}

И сообщение об ошибке: 2020-02-06 15:24:57 error: Failed to move files: Error: Unexpected API Response [400 Bad Request] bad_request - Stream ended unexpectedly.

Любое понимание очень ценится!

1 Ответ

0 голосов
/ 07 февраля 2020

Итак, после более подробного изучения этого вопроса выясняется, что проблема на самом деле связана с Box sdk для Node. SDK завершает тело потока, прежде чем это будет фактически сделано. Это связано с тем, что под капотом они используют библиотеку request, которой для отправки больших полезных данных требуется заголовок content-length. Без этого он будет продолжать прерывать поток перед отправкой полезной нагрузки.

На форуме сообщества Box они предлагают добавить свойства в прототип потока, чтобы передать материал в базовую библиотеку запросов. Я СИЛЬНО не согласен с этим, потому что это не правильный способ go об этом. Box sdk должен предоставить способ передачи длины содержимого в байтах. Как пользователь их API, я не должен манипулировать их зависимостями. Я собираюсь открыть проблему с их SDK и, надеюсь, исправить это.

Надеюсь, что это будет полезно для кого-то еще!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...