Node.js: Comment faire pour lire un flux de données dans une mémoire tampon?
J'ai écrit un assez simple fonction qui télécharge une image à partir d'une URL donnée, de les redimensionner et de les télécharger pour les S3 (à l'aide de 'g' et 'knox), je n'ai aucune idée de si je suis en train de faire la lecture d'un flux vers une mémoire tampon correctement. (tout fonctionne, mais est-ce la bonne voie?)
aussi, je veux comprendre quelque chose au sujet de la boucle d'événements, comment puis-je savoir qu'une invocation de la fonction ne sera pas de fuite de quelque chose ou de changer le 'buf' variable à une autre déjà en cours d'exécution invocation (ou ce scénario est impossible, car les rappels 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);
});
};
Vous devez vous connecter pour publier un commentaire.
Globalement, je ne vois pas ce qui allait se briser dans votre code.
Deux suggestions:
La façon dont vous combinez
Buffer
objets est une sous-optimale car il a copier toutes les données déjà existantes sur tous les "données" de l'événement. Il serait mieux de mettre les morceaux dans un tableau etconcat
tous à la fin.Pour la performance, je veux le regarder dans si le S3 bibliothèque que vous utilisez prend en charge les flux. Idéalement, vous n'avez pas besoin de créer une grande mémoire tampon à tous, et, au lieu de simplement passer les
stdout
flux directement vers le S3 bibliothèque.Comme pour la deuxième partie de votre question, ce n'est pas possible. Lorsqu'une fonction est appelée, elle est allouée à son propre contexte, et tout ce que définies à l'intérieur de qui sera uniquement accessible à partir d'autres éléments définis à l'intérieur de cette fonction.
Mise à jour
Dumping le fichier du système de fichiers signifierait probablement moins de l'utilisation de la mémoire par la demande, mais le fichier IO peut être assez lent, il pourrait ne pas être en vaut la peine. Je dirais que vous ne devriez pas optimiser trop jusqu'à ce que vous pouvez le profil et le stress-test de cette fonction. Si le garbage collector est en train de faire son travail, vous pouvez être overoptimizing.
Avec tout ce que dit, il existe de meilleures façons de toute façon, donc ne l'utilisez pas les fichiers. Depuis tout ce que vous voulez est de la longueur, vous pouvez calculer que, sans avoir besoin d'ajouter tous les tampons ensemble, alors vous n'avez pas besoin d'allouer un nouveau Tampon à tous.
bufs.pop()
appel doit êtrebufs.unshift()
, ou encore plus simple il suffit de remplacer la totalité de la boucle while avec une simple boucle for.Vous pouvez facilement le faire en utilisant nœud-extraction si vous êtes en tirant à partir de l'adresse http(s) Uri.
Du readme:
Un projet connexe est nœud-stream-tampon. Description: "de lecture et d'Écriture des Ruisseaux que l'utilisation de la sauvegarde des Tampons".
Je suggère de tableau de tampons et concat résultant de la mémoire tampon qu'une seule fois à la fin. Il est facile de le faire manuellement, ou que l'on pourrait utiliser nœud-tampons
Je veux juste poster ma solution. Réponse à la question précédente a été très utile pour mes recherches. J'utilise la longueur de cours d'eau pour obtenir la taille de la rivière, mais le problème ici est que le rappel est tiré près de la fin du flux, donc, j'utilise aussi les flux cache à cache le flux et le tuyau à res objet une fois que je connais la longueur du contenu. En cas d'erreur,
Je suggère loganfsmyths méthode, à l'aide d'un tableau pour stocker les données.
DANS mon exemple, je travaille avec GRIDfs et des mnp Jimp.
J'ai fait d'autres recherches
avec une méthode de chaîne mais cela ne fonctionne pas, par pad parce que j'ai été la lecture d'un fichier image, mais la méthode de la baie a fait un travail.
Quand j'ai fait la méthode de chaîne j'ai eu cette erreur de mnp jimp
fondamentalement, je crois que le type encore de la contrainte de binaire en chaîne ne fonctionne pas si bien.