86 votes

Node.js : Comment lire un flux dans un tampon ?

J'ai écrit une fonction assez simple qui télécharge une image à partir d'une URL donnée, la redimensionne et l'upload sur S3 (en utilisant 'gm' et 'knox'), je n'ai aucune idée si je fais la lecture d'un stream vers un buffer correctement. (tout fonctionne, mais est-ce que c'est la bonne façon de faire ?)

De plus, j'aimerais comprendre quelque chose à propos de la boucle événementielle, comment puis-je savoir qu'une invocation de la fonction ne fuira rien ou ne changera pas la variable 'buf' pour une autre invocation déjà en cours (ou bien ce scénario est impossible parce que les callbacks sont des fonctions anonymes ?)

var http = require('http');
var https = require('https');
var s3 = require('./s3');
var gm = require('gm');

module.exports.processImageUrl = function(imageUrl, filename, callback) {
var client = http;
if (imageUrl.substr(0, 5) == 'https') { client = https; }

client.get(imageUrl, function(res) {
    if (res.statusCode != 200) {
        return callback(new Error('HTTP Response code ' + res.statusCode));
    }

    gm(res)
        .geometry(1024, 768, '>')
        .stream('jpg', function(err, stdout, stderr) {
            if (!err) {
                var buf = new Buffer(0);
                stdout.on('data', function(d) {
                    buf = Buffer.concat([buf, d]);
                });

                stdout.on('end', function() {
                    var headers = {
                        'Content-Length': buf.length
                        , 'Content-Type': 'Image/jpeg'
                        , 'x-amz-acl': 'public-read'
                    };

                    s3.putBuffer(buf, '/img/d/' + filename + '.jpg', headers, function(err, res) {
                        if(err) {
                            return callback(err);
                        } else {
                            return callback(null, res.client._httpMessage.url);
                        }
                    });
                });
            } else {
                callback(err);
            }
        });
    }).on('error', function(err) {
        callback(err);
    });
};

1voto

Andrey Sidorov Points 9287

Je suggère d'avoir un tableau de tampons et de concaténer le tampon résultant une seule fois à la fin. C'est facile à faire manuellement, ou on peut utiliser tampons de nœuds

1voto

Je souhaite simplement publier ma solution. Les réponses précédentes ont été très utiles pour mes recherches. J'utilise length-stream pour obtenir la taille du flux, mais le problème ici est que le callback est déclenché vers la fin du flux, donc j'utilise aussi stream-cache pour mettre en cache le flux et l'acheminer vers l'objet res une fois que je connais le contenu-longueur. En cas d'erreur,

var StreamCache = require('stream-cache');
var lengthStream = require('length-stream');

var _streamFile = function(res , stream , cb){
    var cache = new StreamCache();

    var lstream = lengthStream(function(length) {
        res.header("Content-Length", length);
        cache.pipe(res);
    });

    stream.on('error', function(err){
        return cb(err);
    });

    stream.on('end', function(){
        return cb(null , true);
    });

    return stream.pipe(lstream).pipe(cache);
}

1voto

afcfzf Points 29

Dans ts, [].push(bufferPart) n'est pas compatible ;

donc :

getBufferFromStream(stream: Part | null): Promise<Buffer> {
    if (!stream) {
        throw 'FILE_STREAM_EMPTY';
    }
    return new Promise(
        (r, j) => {
            let buffer = Buffer.from([]);
            stream.on('data', buf => {
               buffer = Buffer.concat([buffer, buf]);
            });
            stream.on('end', () => r(buffer));
            stream.on('error', j);
        }
    );
}

0voto

faBri_CI-o Points 13

Vous pouvez vérifier le "content-length" (longueur du contenu) dans res.headers. Il vous donnera la longueur du contenu que vous recevrez (le nombre d'octets de données qu'il enverra).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X