J'ai besoin de faire une analyse de grands fichiers journaux (5-10 Go) dans Javascript / Node.js (j'utilise Cube).
La ligne de connexion ressemble à quelque chose comme:
10:00:43.343423 I'm a friendly log message. There are 5 cats, and 7 dogs. We are in state "SUCCESS".
Nous devons lire chaque ligne, faire une analyse (par exemple, supprimer 5
, 7
et SUCCESS
), puis pomper ces données dans Cube ( https://github.com/square/cube ) en utilisant leur client JS.
Premièrement, quelle est la manière canonique dans Node de lire dans un fichier, ligne par ligne?
Cela semble être une question assez courante en ligne:
- http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
- Lire un fichier une ligne à la fois dans node.js?
Beaucoup de réponses semblent pointer vers un tas de modules tiers:
- https://github.com/nickewing/line-reader
- https://github.com/jahewson/node-byline
- https://github.com/pkrumins/node-lazy
- https://github.com/Gagle/Node-BufferedReader
Cependant, cela semble être une tâche assez basique - il existe sûrement un moyen simple dans stdlib de lire dans un fichier texte, ligne par ligne?
Deuxièmement, je dois ensuite traiter chaque ligne (par exemple, convertir l'horodatage en un objet Date et extraire les champs utiles).
Quelle est la meilleure façon de faire cela, en maximisant le débit? Y a-t-il un moyen qui ne bloque pas la lecture de chaque ligne ou son envoi à Cube?
Troisièmement - je suppose que l'utilisation de séparations de chaînes, et l'équivalent JS de contains (IndexOf! = -1?) Sera beaucoup plus rapide que les expressions rationnelles? Quelqu'un a-t-il eu beaucoup d'expérience dans l'analyse de quantités massives de données texte dans Node.js?
Bravo, Victor
la source
Réponses:
J'ai cherché une solution pour analyser les très gros fichiers (gbs) ligne par ligne en utilisant un flux. Toutes les bibliothèques et exemples tiers ne répondaient pas à mes besoins car ils ne traitaient pas les fichiers ligne par ligne (comme 1, 2, 3, 4 ..) ni ne lisaient le fichier entier en mémoire
La solution suivante peut analyser des fichiers très volumineux, ligne par ligne, en utilisant stream & pipe. Pour les tests, j'ai utilisé un fichier de 2,1 Go avec 17 000 000 enregistrements. L'utilisation de la RAM n'a pas dépassé 60 mb.
Tout d'abord, installez le package de flux d'événements :
Ensuite:
S'il vous plaît laissez-moi savoir comment ça se passe!
la source
console.log(lineNr)
après la dernière ligne de votre code, il n'affichera pas le nombre de lignes final car le fichier est lu de manière asynchrone.s.end();
readline
module est une douleur. Il ne se met pas en pause et provoquait un échec à chaque fois après 40 à 50 millions. Perdu une journée. Merci beaucoup pour la réponse. Celui-ci fonctionne parfaitementVous pouvez utiliser le
readline
package intégré , voir la documentation ici . J'utilise stream pour créer un nouveau flux de sortie.Le traitement des gros fichiers prendra un certain temps. Dites si cela fonctionne.
la source
readline
, est-il possible de mettre en pause / reprendre le flux de lecture pour effectuer des actions asynchrones dans la zone «faire des choses»?readline
me posait beaucoup de problèmes lorsque j'ai essayé de mettre en pause / reprendre. Cela ne met pas correctement le flux en pause, ce qui crée beaucoup de problèmes si le processus en aval est plus lentJ'ai vraiment aimé la réponse @gerard qui mérite en fait d'être la bonne réponse ici. J'ai apporté quelques améliorations:
Voici le code:
Donc, en gros, voici comment vous allez l'utiliser:
J'ai testé cela avec un fichier CSV de 35 Go et cela a fonctionné pour moi et c'est pourquoi j'ai choisi de le construire sur la réponse de @gerard , les commentaires sont les bienvenus.
la source
pause()
appel, n'est-ce pas?J'ai utilisé https://www.npmjs.com/package/line-by-line pour lire plus de 1000000 lignes à partir d'un fichier texte. Dans ce cas, une capacité occupée de RAM était d'environ 50 à 60 mégaoctets.
la source
lr.cancel()
méthode. Lit les 1000 premières lignes d'un fichier 5Gig en 1 ms. Impressionnant!!!!En plus de lire le gros fichier ligne par ligne, vous pouvez également le lire morceau par morceau. Pour en savoir plus, consultez cet article
la source
if(bytesRead = chunkSize)
:?La documentation Node.js offre un exemple très élégant utilisant le module Readline.
Exemple: lire le flux de fichiers ligne par ligne
la source
J'ai encore eu le même problème. Après avoir comparé plusieurs modules qui semblent avoir cette fonctionnalité, j'ai décidé de le faire moi-même, c'est plus simple que je ne le pensais.
gist: https://gist.github.com/deemstone/8279565
Il couvre le dossier ouvert dans une fermeture, que
fetchBlock()
retourné récupérera un bloc du fichier, finira par diviser en tableau (traitera le segment de la dernière récupération).J'ai défini la taille du bloc sur 1024 pour chaque opération de lecture. Cela peut avoir des bogues, mais la logique du code est évidente, essayez-la vous-même.
la source
node-byline utilise des flux, donc je préférerais celui-là pour vos gros fichiers.
pour vos conversions de date, j'utiliserais moment.js .
pour maximiser votre débit, vous pourriez envisager d'utiliser un cluster logiciel. il y a quelques modules sympas qui enveloppent assez bien le module de cluster natif du nœud. j'aime cluster-master d'isaacs. par exemple, vous pouvez créer un cluster de x workers qui calculent tous un fichier.
pour l'analyse comparative entre les divisions et les expressions régulières, utilisez benchmark.js . je ne l'ai pas testé jusqu'à présent. benchmark.js est disponible en tant que module de nœud
la source
Sur la base de cette réponse aux questions, j'ai implémenté une classe que vous pouvez utiliser pour lire un fichier de manière synchrone ligne par ligne avec
fs.readSync()
. Vous pouvez faire cette "pause" et "reprendre" en utilisant uneQ
promesse (jQuery
semble nécessiter un DOM donc je ne peux pas l'exécuter avecnodejs
):la source
la source
J'ai créé un module de nœud pour lire du texte ou JSON de gros fichiers de manière asynchrone. Testé sur de gros fichiers.
Enregistrez simplement le fichier sous le nom file-reader.js et utilisez-le comme ceci:
la source