2017-08-03 3 views
1

Brève:
Un système qui charge les fichiers CSV, mais ils devraient être énormes (lignes + 1M). J'ai déjà une idée sur la façon de les traiter en utilisant les files d'attente et les tâches/tâches d'arrière-plan.Comment connaître le nombre de lignes dans un fichier sans charger son contenu dans la mémoire en JavaScript?

Mais,
Je veux afficher à l'utilisateur un progrès dans son dossier, la ligne de quelque chose: 2165 de 1.246.875 ou peut-être le pourcentage de celui-ci. Pour archiver cela, j'ai besoin de connaître le nombre de lignes dans le fichier, mais je dois le faire sans charger son contenu dans la mémoire, donc il peut être rapide, dès que je reçois un téléchargement et peut enregistrer le nom de fichier dans le des lignes totales y sont trouvées.

En PHP cela est possible en utilisantSplFileObject essayant de seek() au PHP_MAX_INT, il va à la plus haute ligne, il peut dans le fichier et key() rendements ligne.

Mais le système est en cours de construction entièrement dans JavaScript/Node.js donc, par commodité, je veux aussi construire cette partie du système en JavaScript.

Comment pourrais-je accomplir cela? Déjà jeté un coup d'oeil à FS API, mais n'a pas trouvé comment à cela.

[EDIT]
Idées jusqu'à présent:

  1. child_process.exec + wc -l (Unix uniquement)
  2. obtenir cette information du client à l'aide FileReader (ressources délégué à l'utilisateur)
+0

Vous pouvez lire certaines premières lignes, calculer la taille moyenne de la ligne et diviser la taille du fichier. –

+0

Quelqu'un me corrige si je me trompe, mais si vous lisez le fichier async et ne spécifiez pas un encodage de fichier, vous ne gérez que les morceaux, n'est-ce pas? Alors pourriez-vous compter les sauts de ligne dans chaque morceau et laisser le morceau récupérer les ordures? –

+1

Vous n'avez pas besoin de compter les lignes. Gardez une trace du nombre d'octets traités et divisez-le par la longueur du fichier pour connaître la quantité du fichier que vous avez déjà traité. Multipliez par 100 pour l'exprimer en pourcentage. – axiac

Répondre

0

Vous utiliseriez un flux tel que documenté here

L'exemple suivant pourrait indiquer le nombre de lignes dans un fichier, en utilisant le premier argument comme nom de fichier.

ie: noeud countlines.js nameoffiletocountthelines.csv

var fs = require("fs"); 

var lines = 0; 
//Using the first argument as the filename 
var filename = process.argv[2]; 

var stream = fs.createReadStream(filename) 

//When data is received, check all the character codes and 
//if we find a carriage return, increment the line counter 
stream.on("data", function(chunk) { 
    for(var i = 0; i < chunk.length; i++) { 
     if (chunk[i] == 10 || chunk[i] == 13) lines++; 
    } 
}); 

//When the file processing is done, echo the number of lines 
stream.on("end", function() { 
    console.log("Lines: " + lines); 
}); 
+0

Merci, mais il semble que cela n'empêche pas le contenu du fichier d'être ajouté à la mémoire. J'ai testé avec un fichier CSV de 134.091.524 octets et le 'process.memoryUsage()' de 'de' a rapporté 106.373.180 octets d'utilisation externe. –

1

Ceci est impossible.

Les lignes sont un concept humain concernant un fichier. Pour les ordinateurs, les fichiers ne sont qu'un tas d'octets; vous pouvez connaître le nombre total d'octets, vous pouvez rechercher la longueur des octets de pensée, mais sachant combien de lignes ont ces octets envolves compter les sauts de ligne et compter les sauts de ligne envolves de les lire.

Les deux wc et PHP SplFileObject flux le fichier entier, ils ne font pas magie. La meilleure réponse est donc la méthode la plus efficace. Ce qui signifie que le GC fonctionnerait mieux. En revanche, si la précision n'est pas une exigence, vous pouvez essayer de deviner. Si toutes les lignes ont une longueur d'octets fixe, vous pouvez le diviser par le nombre total d'octets du fichier.Ou, comme pointed by Aikon, vous pouvez lire seulement quelques octets (ils se séparent en lignes) obtenir la longueur moyenne d'entre eux et diviser par le nombre total d'octets du fichier.

Bien qu'il apporte le contenu du fichier dans la mémoire, la réponse Joel Lord est la réponse pour une solution Node.js. Vous pouvez également jeter un oeil à readline module.

+0

* sachant combien de lignes ont ces octets envol qui comptent les sauts de ligne * Exactement. Vous pouvez aussi penser à "compter les lignes" comme "compter les caractères de nouvelle ligne" (les appeler "sauts de ligne" peut être déroutant pour certains), parce que c'est ce qui définit une "ligne". Et pour * compter * les caractères de nouvelle ligne, vous devez trouver * tout * d'entre eux. Ce qui signifie lire le fichier * entier *. –