Обтекание потока nodejs в объекте JSON

У меня есть читаемый поток, что-то вроде этого:

const algorithm = 'aes-256-ctr';
stream = file.stream
    .pipe(crypto.createCipher(algorithm, encryptionKey))
    .pipe(outStream);

Шифрование работает, как и ожидалось, для всего файла. Мне нужно обернуть результат crypto в какой-то json, поэтому поток вывода должен получить что-то вроде этого:

{
    "content": "/* MY STREAM CONTENT */"
}

как я это сделал?

Кроме того, мне нужно прочитать файл, хранящийся на диске, и развернуть его из json, если ключ шифрования совпадает.

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

1 ответ

Начиная с узла v13, вы можете использовать генераторы внутриpipeline и создайте свой объект как строку:

      // const { pipeline } = require('stream/promises'); // <- node >= 16
const Util = require('util');
const pipeline = Util.promisify(Stream.pipeline);

const algorithm = 'aes-256-ctr';
const Crypto = require('crypto');

async function run() {
  await pipeline(
    file.stream, // <- your file read stream
    Crypto.createCipher(algorithm, encryptionKey),
    chunksToJson,
    outStream
  );
}

async function* chunksToJson(chunksAsync) {
  yield '{"content": "';
  for await (const chunk of chunksAsync) {
    yield Buffer.isBuffer(chunk) ? chunk.toString('utf8') : JSON.stringify(chunk);
  }
  yield '"}';
}

Предполагая более сложный случай, когда передается большой объем данных (что обычно имеет место при использовании потоков), у вас может возникнуть соблазн сделать что-то вроде следующего. Это не очень хорошая практика, поскольку все content будет накапливаться в памяти, прежде чем уступить, нарушая цель потоковой передачи.

      async function* chunksToJson(chunksAsync) {
  const json = { content: [] };
  for await (const chunk of chunksAsync) {
    json.content.push(Buffer.isBuffer(chunk) ? chunk.toString('utf8') : JSON.stringify(chunk));
  }
  yield JSON.stringify(json);
}
Другие вопросы по тегам