Lire un fichier ou plus généralement un flux de données ligne par ligne est une opération triviale pour toutes les personnes connaissant la fonction fgets
. Voici 4 méthodes pour résoudre cette problématique basique avec NodeJS :
0. String & Split
C'est la méthode la plus simple, il suffit de charger la totalité du fichier dans une chaîne de caractères puis découper cette chaîne en fonction du caractère \n
#!/usr/bin/env node var buffer = ''; process.stdin.resume(); process.stdin.setEncoding('utf8'); process.stdin.on('data', function (chunk) { buffer += chunk; }); process.stdin.on('end', function () { buffer.split('\n').forEach(function(line) { process.stdout.write(line); process.stdout.write('\n'); }); });
1. Module byline
#!/usr/bin/env node var byline = require('byline'); process.stdin.resume(); process.stdin.setEncoding('utf8'); stream = byline.createLineStream(process.stdin); stream.on('data', function(line) { process.stdout.write(line); process.stdout.write('\n'); }); stream.on('end', function() { // Ended ! });
2. Module carrier
#!/usr/bin/env node var carrier = require('carrier'); process.stdin.resume(); process.stdin.setEncoding('utf8'); carrier.carry(process.stdin, function(line) { process.stdout.write(line); process.stdout.write('\n'); });
3. Module line-reader
#!/usr/bin/env node var lineReader = require('line-reader'); lineReader.eachLine('/dev/stdin', function(line, last) { process.stdout.write(line); process.stdout.write('\n'); });
4. Module node-each-line
#!/usr/bin/env node var each_line = require('./each_line').each_line; each_line(process.stdin, function (line) { process.stdout.write(line); });
Comparaison
Pour faire son choix, il est intéressant de comparer leur performance pour cela
on commence par les installer:
npm install byline npm install carrier npm install line-reader wget https://raw.github.com/aaronj1335/node-each-line/master/each_line.js
Ensuite, on utilise un fichier qui va générer quelques milliers de lignes :
#!/usr/bin/env node for(var i = 1; i <= 100000; i++) { process.stdout.write(i+''); process.stdout.write('\n'); }
Reste à exécuter le tout :
$ time ./input.js | ./00.js >/dev/null real 0m14.753s user 0m14.973s sys 0m1.288s $ time ./input.js | ./01.js >/dev/null real 0m11.714s user 0m11.885s sys 0m1.204s $ time ./input.js | ./02.js >/dev/null real 0m11.495s user 0m11.761s sys 0m1.164s $ time ./input.js | ./03.js >/dev/null node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Socket is not writable at Socket._writeOut (net.js:391:11) at Socket.write (net.js:377:17) at Object.<anonymous> (/home/thouveni/Tests/node/lines/input.js:4:17) at Module._compile (module.js:402:26) at Object..js (module.js:408:10) at Module.load (module.js:334:31) at Function._load (module.js:293:12) at Array.<anonymous> (module.js:421:10) at EventEmitter._tickCallback (node.js:126:26) real 0m0.057s user 0m0.068s sys 0m0.036s $ time ./input.js | ./04.js >/dev/null real 0m5.096s user 0m5.764s sys 0m0.624s
Conclusion
Le module line-reader ne fonctionne pas, à ignorer. Les modules carrier et byline sont équivalents. Et le script node-each-line est le plus rapide mais il ne permet pas d'intercepter la fin de fichier. Le choix est donc une affaire de gout. Personnellement, j'utilise byline.
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimer