在JSON对象中包装nodejs流

时间:2017-10-09 19:33:25

标签: json node.js stream transform-stream

我有一个可读的流,如下所示:

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

加密在整个文件中按预期工作。 我需要将crypto的结果包装成某种json,所以输出流接收这样的东西:

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

我该怎么做?

此外,如果加密密钥匹配,我需要读取存储在磁盘上的文件并从json中解包。

提前致谢

1 个答案:

答案 0 :(得分:1)

从节点 v13 开始,您可以在 generators 中使用 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);
}