2013-11-11 2 views
19

Как преобразовать поток в буфер в nodejs? Вот мой код для анализа файла в почтовом запросе в экспресс.Преобразование потока в буфер?

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

ответ

11

Вы можете использовать модуль 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 stream. В качестве записывающего средства реализации потока вам нужно только определить одну функцию: _write method, которая будет вызываться каждый раз, когда некоторые данные записываются в поток. Когда поток ввода будет завершен, данные будут испускать: end event: мы создадим буфер, используя Buffer.concat method.

var stream = require('stream'); 
var converter = new stream.Writable(); 
converter.data = []; // We'll store all the data inside this array 
converter._write = function (chunk) { 
    this.data.push(chunk); 
}; 
converter.on('end', function() { // Will be emitted when the input stream has ended, ie. no more data will be provided 
    var b = Buffer.concat(this.data); // Create a buffer from all the received chunks 
    // Insert your business logic here 
}); 
+2

Для записываемых потоков, я считаю, что событие «закончено», а не «конец». Оба они означают одно и то же, но их нужно назвать по-другому, потому что они сосуществуют на Трансформации. https://nodejs.org/api/stream.html#stream_event_finish – noderman

18

Вместо труб, вы можете прикрепить data и end обработчиков событий в part поток, чтобы читать:

var buffers = []; 
part.on('data', function(buffer) { 
    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... 
    }); 
}); 

Однако это будет прочитать всю загрузку в память. Если это проблема, вы можете подумать о создании настраиваемого transform stream для преобразования входящих данных, но это может быть не тривиально.

Смежные вопросы