38

如何在nodejs中将流转换为缓冲区?这是我在 express 中解析 post 请求中的文件的代码。

app.post('/upload', express.multipart({
defer: true
}), function(req, res) {
req.form.on('part', function(part) {

//Here I want to convert the streaming part into a buffer.
//do something buffer-specific task

  var out = fs.createWriteStream('image/' + part.filename);
  part.pipe(out);
});

req.form.on('close', function() {
    res.send('uploaded!');
  });
});
4

2 回答 2

46

代替管道,您可以将事件处理程序附加到readable流以读取它:endpart

var buffers = [];
part.on('readable', function(buffer) {
  for (;;) {
    let buffer = part.read();
    if (!buffer) { break; }
    buffers.push(buffer);
  }
});
part.on('end', function() {
  var buffer = Buffer.concat(buffers);
  ...do your stuff...

  // write to file:
  fs.writeFile('image/' + part.filename, buffer, function(err) {
    // handle error, return response, etc...
  });
});

注意:如果您改为使用data,它会将整个上传内容读入内存。

您还可以创建自定义转换流来转换传入的数据,但这可能并非易事。

于 2013-11-11T14:53:16.970 回答
25

您可以使用该stream-to模块,它可以将可读流的数据转换为数组或缓冲区:

var streamTo = require('stream-to');
req.form.on('part', function (part) {
    streamTo.buffer(part, function (err, buffer) {
        // Insert your business logic here
    });
});

如果您想更好地了解幕后发生的事情,您可以自己实现逻辑,使用Writable。作为可写流的实现者,您只需要定义一个函数:_write方法,每次将一些数据写入流时都会调用该函数。当输入流完成发送数据时,将发出end事件:然后我们将使用Buffer.concat方法创建一个缓冲区。

var stream = require('stream');
var converter = new stream.Writable();

// We'll store all the data inside this array
converter.data = [];
converter._write = function (chunk) {
    converter.data.push(chunk);
};

// Will be emitted when the input stream has ended, 
// i.e. no more data will be provided
converter.on('finish', function() {
    // Create a buffer from all the received chunks
    var b = Buffer.concat(this.data);

    // Insert your business logic here
});
于 2013-11-11T14:54:26.260 回答