如何从可写流中创建可读流?(Node.js的)

Max*_*ber 8 stream node.js

我正在使用Exceljs动态创建Excel数据

我想在内存中缓冲这个东西,然后使用Koa将它发送给用户.

writeExceljs 的方法需要一个writableStream:

workbook.xlsx.write(writableStream, options)

但Koa希望有一个可读的流:

response.body = readableStream

我知道我可以将可读流传输到可写流中,但是我该怎么做?我希望Exceljs写入可写流并让Koa从同一个流中读取.我对流API感到非常沮丧!

在其他20件事中,我试过这个:

const ReadableStream = require("memory-streams").ReadableStream

const reader = new ReadableStream()

const writer = new stream.Writable({
    write: function(chunk, encoding, next) {
        console.log(chunk.toString())
        // reader.push(chunk, encoding)
        next()
    }
})

const reader = new MemoryStream(null, {readable: true})
// reader.write = reader.unshift
const writer = reader

workbook.xlsx.write(writer, {})
return reader
Run Code Online (Sandbox Code Playgroud)

但它不起作用,我得到一些奇怪的错误,关于无法写入已关闭的流.但是,即使我处理错误,我的Excel文件也无法打开.

那么如何从可写流中创建可读流?

Jav*_*iri 8

你考虑过Passthrough 流吗?这是一个简单的转换流,它将传递给它的所有数据传递给它,因此您可以从可写流中读取。


use*_*271 7

您需要一个变换流.它既可读又可写.

stream = new require('stream').Transform()
stream._transform = function (chunk,encoding,done) 
{
    this.push(chunk)
    done()
}
Run Code Online (Sandbox Code Playgroud)

  • 我看了文档,头都麻木了。有什么建议么?我正在寻找一些愚蠢的东西,比如等同于恒等函数:一个不做任何事情的转换。 (3认同)
  • 有几件事无法理解正在发生的事情......你如何使用这个“Transform”?如何将其传输到可写/可读流(这是最初的问题)? (2认同)

Gui*_*sse 6

对于所有需要可写和可读流的人。这就是最终对我有用的方法。

用例是仅使用 stream.Writable --> 仅使用 stream.Readable 从动态变量(例如:userId)生成 QRCode png 图像的 QRCode 包上传到 AWS S3 存储桶。

import QRCode from 'qrcode';
import AWS from 'aws-sdk';
import { Transform } from 'stream';

const userId = 'userIdString';

// AWS Config, import this from a safe place!!!
AWS.config.update({
  accessKeyId: 'xxxxxxxxxx',
  secretAccessKey: 'xxxxxxxxx',
  region: 'xxxxxxx',
});

const s3 = new AWS.S3({ apiVersion: '2006-03-01' });

// Create Stream, Writable AND Readable
const inoutStream = new Transform({
  transform(chunk, encoding, callback) {
    this.push(chunk);
    callback();
  },
});

// Need writable stream
QRCode.toFileStream(inoutStream, userId);

//Just to check
inoutStream.on('finish', () => {
  console.log('finished writing');
});

// Need readable stream
  s3.upload(
    {
      Bucket: 'myBucket',
      Key: `QR_${userId}.png`,
      Body: inoutStream,
      // ACL: 'public-read',
      ContentType: 'image/png',
    },
    (err, data) => {
      console.log(err, data);
    },
  )
  .on('httpUploadProgress', (evt) => {
    console.log(evt);
  })
  .send((err, data) => {
    console.log(err, data);
  });
Run Code Online (Sandbox Code Playgroud)

如果您之前从未使用过流,这是一个非常好的来源。