node.js - stringdecoder - convertir búferes transmitidos en flujo a utf8-string
read a buffer node (2)
Quiero hacer una solicitud HTTP utilizando node.js para cargar texto de un servidor web. Como la respuesta puede contener mucho texto (algunos megabytes), quiero procesar cada fragmento de texto por separado. Puedo lograr esto usando el siguiente código:
var req = http.request(reqOptions, function(res) {
...
res.setEncoding(''utf8'');
res.on(''data'', function(textChunk) {
// process utf8 text chunk
});
});
Esto parece funcionar sin problemas. Sin embargo, quiero admitir la compresión HTTP, así que uso zlib:
var zip = zlib.createUnzip();
// NO res.setEncoding(''utf8'') here since we need the raw bytes for zlib
res.on(''data'', function(chunk) {
// do something like checking the number of bytes downloaded
zip.write(chunk); // give the raw bytes to zlib, s.b.
});
zip.on(''data'', function(chunk) {
// convert chunk to utf8 text:
var textChunk = chunk.toString(''utf8'');
// process utf8 text chunk
});
Esto puede ser un problema para caracteres de varios bytes como ''/u00c4''
que consta de dos bytes: 0xC3
y 0x84
. Si el primer byte está cubierto por el primer fragmento ( Buffer
) y el segundo byte por el segundo, entonces chunk.toString(''utf8'')
producirá caracteres incorrectos al final / principio del fragmento de texto. ¿Cómo puedo evitar esto?
Sugerencia: aún necesito el buffer (más específicamente el número de bytes en el buffer) para limitar el número de bytes descargados. Así que usar res.setEncoding(''utf8'')
como en el primer código de ejemplo anterior para datos no comprimidos no se ajusta a mis necesidades.
Solo Buffer
Si tiene un único Buffer
, puede usar su método toString
que convertirá todo o parte del contenido binario en una cadena utilizando una codificación específica. El valor predeterminado es utf8
si no proporciona un parámetro, pero he establecido explícitamente la codificación en este ejemplo.
var req = http.request(reqOptions, function(res) {
...
res.on(''data'', function(chunk) {
var textChunk = chunk.toString(''utf8'');
// process utf8 text chunk
});
});
Búfers de transmisión por secuencias
Si tiene búferes distribuidos como en la pregunta anterior, donde el primer byte de un carácter UTF8
varios bytes puede estar contenido en el primer Buffer
(fragmento) y el segundo byte en el segundo Buffer
entonces debe usar un StringDecoder
. :
var StringDecoder = require(''string_decoder'').StringDecoder;
var req = http.request(reqOptions, function(res) {
...
var decoder = new StringDecoder(''utf8'');
res.on(''data'', function(chunk) {
var textChunk = decoder.write(chunk);
// process utf8 text chunk
});
});
De esta forma, los bytes de los caracteres incompletos se almacenan en búfer por StringDecoder
hasta que se StringDecoder
todos los bytes necesarios en el decodificador.
var fs = require("fs");
function readFileLineByLine(filename, processline) {
var stream = fs.createReadStream(filename);
var s = "";
stream.on("data", function(data) {
s += data.toString(''utf8'');
var lines = s.split("/n");
for (var i = 0; i < lines.length - 1; i++)
processline(lines[i]);
s = lines[lines.length - 1];
});
stream.on("end",function() {
var lines = s.split("/n");
for (var i = 0; i < lines.length; i++)
processline(lines[i]);
});
}
var linenumber = 0;
readFileLineByLine(filename, function(line) {
console.log(++linenumber + " -- " + line);
});