Node.js 使用流将base64写入文件

Node.js 使用流将base64写入文件,node.js,express,Node.js,Express,我正在向服务器发送base64字符串。在服务器上,我想创建一个可读的流,将base64块推送到该流上,然后转到一个可写流并写入文件。我的问题是只有第一个块被写入文件。我的猜测是因为我为每个区块创建了一个新的缓冲区,这就是导致问题的原因,但是如果我只发送字符串区块而不创建缓冲区,那么图像文件就会损坏 var readable = new stream.Readable(); readable._read = function() {} req.on('data', function(data)

我正在向服务器发送base64字符串。在服务器上,我想创建一个可读的流,将base64块推送到该流上,然后转到一个可写流并写入文件。我的问题是只有第一个块被写入文件。我的猜测是因为我为每个区块创建了一个新的缓冲区,这就是导致问题的原因,但是如果我只发送字符串区块而不创建缓冲区,那么图像文件就会损坏

var readable = new stream.Readable();

readable._read = function() {}

req.on('data', function(data) {
    var dataText = data.toString();
    var dataMatch = dataText.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
    var bufferData = null;

    if (dataMatch) {
        bufferData = new Buffer(dataMatch[2], 'base64')
    }

    else {
        bufferData = new Buffer(dataText, 'base64')
    }

    readable.push(bufferData)
})

req.on('end', function() {
    readable.push(null);
})

这并不像你想象的那么简单:

  • 使用
    转换
    ,而不是
    可读
    。您可以
    pipe
    请求流进行转换,从而处理背压

  • 您不能使用正则表达式,因为您期望的文本可能会被分成两个或多个块。您可以尝试每次累积数据块和exec正则表达式,但如果流的格式不正确(即,不是
    data
    uri),则最终会对整个请求进行缓冲,并在兆字节长的字符串上多次运行正则表达式

  • 您不能获取任意块并执行
    新建缓冲区(块,'base64')
    ,因为它本身可能无效。例如:
    newbuffer('AQID','base64')
    产生
    newbuffer([1,2,3])
    ,但
    Buffer.concat([newbuffer('AQ','base64')、newbuffer('ID','base64'))
    产生
    newbuffer([1,32])

  • 对于3个问题,您可以使用一个可用的模块(如)。以下是一个例子:

    var base64 = require('base64-stream');
    var stream = require('stream');
    
    var decoder = base64.decode();
    var input = new stream.PassThrough();
    var output = new stream.PassThrough();
    
    input.pipe(decoder).pipe(output);
    
    output.on('data', function (data) {
      console.log(data);
    });
    
    input.write('AQ');
    input.write('ID');
    
    您可以看到,它缓冲输入并在足够的数据到达时发出
    数据


    至于第2个问题,您需要实现简单的流解析器。一个想法是:等待
    数据:
    字符串,然后缓冲块(如果需要),直到
    ;base64,
    找到,然后通过管道连接到
    base64流

    谢谢@vkurchatkin!我不确定我是否完全听懂了你的话。我想把每一块推到流中。我有一个有效的解决方案,使用on('data')和concating每个块,然后创建一个缓冲区并推送到流上,但正如我所说的,我希望流式处理每个块。我在发布这个问题之前尝试了base64 stream,但没有使它起作用。你能给出一个简单的代码示例吗。