2014-06-14 69 views
2

我發送一個base64字符串到我的服務器。在服務器上,我想創建一個可讀的流,我將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); 
}) 

回答

5

這並不像你想象的那麼簡單:

  1. 使用Transform,不Readable。您可以將pipe請求流轉換,從而處理背壓。

  2. 您不能使用正則表達式,因爲您期望的文本可能會在兩個或更多的塊中被分解。您可以嘗試每次累加塊和執行正則表達式,但如果流的格式不正確(即,不是data uri),您將最終緩衝整個請求並以兆字節長的字符串運行正則表達式很多次。

  3. 你不能拿任意塊並且做new Buffer(chunk, 'base64')因爲它本身可能不是有效的。例如:new Buffer('AQID', 'base64')產生new Buffer([1, 2, 3]),但Buffer.concat([new Buffer('AQ', 'base64'), new Buffer('ID', 'base64')])產生new Buffer([1, 32])

對於3問題就可以使用可用的模塊中的一個(像base64-stream)。這裏有一個例子:

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'); 

你可以看到它緩衝輸入並儘快到達足以發出data

至於第2個問題,您需要實現簡單的流解析器。作爲一個想法:等待data:字符串,然後緩衝塊(如果你需要它們),直到找到;base64,,然後管道到base64-stream

+0

謝謝@vkurchatkin!我不確定我是否遵循你所說的全部內容。我想推入每個塊,因爲它到達流。我有一個工作解決方案('數據'和concatement每個塊,然後創建一個緩衝區並推入到流,但正如我所說我想流每個塊。我試着base64流簡要之前,我發佈這個問題,但沒有你可以給出一個簡單的代碼示例 – codedmart

+0

@codedmart肯定 – vkurchatkin

+0

好的再次感謝@vkurchatkin。 – codedmart