2017-08-03 3 views
1

Brief:
Ein System, die CSV-Dateien geladen werden kann, aber sie sind zu erwarten riesige (+ 1 M Zeilen) sein. Ich habe bereits eine Idee, wie man sie mit Warteschlangen und Hintergrundjobs/Aufgaben bearbeitet.Wie kann man die Anzahl der Zeilen in einer Datei kennen, ohne ihren Inhalt in den Speicher in JavaScript zu laden?

Aber
Ich mag den Benutzer einen Fortschritt auf seiner Akte, etwas Zeile anzuzeigen: 2165 von 1.246.875 oder vielleicht der Prozentsatz davon. Um dies zu archivieren, muss ich die Anzahl der Zeilen in der Datei kennen, aber ich muss dazu, ohne seinen Inhalt in den Speicher zu laden, also kann es schnell sein, sobald ich einen Upload habe und den Dateinamen innerhalb der Datei speichern kann insgesamt Zeilen darin gefunden.

In PHP ist dies möglichSplFileObject zum PHP_MAX_INT-seek() versuchen verwenden, dann geht es auf die höchste Linie kann es in der Datei und key() kehrt die Linie.

Aber das System wird vollständig in JavaScript/Node.js so gebaut, nur aus Bequemlichkeit, ich möchte diesen Systemteil auch in JavaScript bauen.

Wie konnte ich das erreichen? Bereits einen Blick auf FS API geworfen, aber nicht gefunden, wie dazu.

[EDIT]
Ideen so weit:

  1. child_process.exec + wc -l (nur Unix)
  2. diese Informationen von dem Client Get FileReader (Delegate Ressourcen für den Benutzer) mit
+0

Sie können einige erste Zeilen lesen, die durchschnittliche Größe der Zeile kalkulieren und die Dateigröße aufteilen. –

+0

Jemand korrigiert mich, wenn ich falsch liege, aber wenn Sie die Datei async lesen und keine Dateicodierung angeben, behandeln Sie nur die Brocken, richtig? Könnten Sie die Zeilenumbrüche in jedem Chunk zählen und den Chunk Müll sammeln lassen? –

+1

Sie müssen die Zeilen nicht zählen. Verfolgen Sie die Anzahl der verarbeiteten Bytes und teilen Sie sie durch die Dateilänge, um zu wissen, wie viel von der Datei Sie bereits verarbeitet haben. Multiplizieren Sie mit 100, um es als Prozentsatz auszudrücken. – axiac

Antwort

0

Sie würden einen Stream wie dokumentiert verwenden here

Das folgende Beispiel sollte die Anzahl der Zeilen in einer Datei enthalten, wobei das erste Argument als Dateiname verwendet wird.

dh: Knoten 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

Danke, aber das verhindert nicht das Hinzufügen von Dateiinhalten zum Speicher. Ich testete mit einer 134.091.524 Bytes CSV und Node 'process.memoryUsage()' berichtete 106.373.180 Byte externe Nutzung. –

1

Dies ist unmöglich.

Linien sind ein menschliches Konzept über eine Datei. Für Computer sind Dateien nur ein paar Bytes; Sie können die Gesamtanzahl der Bytes kennen, Sie können die Länge der Gedankenbytes suchen, aber wenn Sie wissen, wie viele Zeilen diese Bytes zählen, zählt das Zählen von Zeilenumbrüchen und das Zählen von Zeilenumbrüchen zum Lesen.

Beide wc und PHP SplFileObject Streams die gesamte Datei, sie machen keine Magie. Die beste Antwort ist also, welche Methode dies am effizientesten macht. Was bedeutet, was GC besser funktionieren würde.

Auf der anderen Seite, wenn Genauigkeit keine Voraussetzung ist, können Sie versuchen, zu erraten. Wenn alle Zeilen eine feste Byte-Länge haben, können Sie sie durch die gesamten Bytes der Datei teilen.Oder, als pointed by Aikon, können Sie nur ein paar Bytes lesen (sie brechen in Zeilen) bekommen die durchschnittliche Länge von ihnen und dividieren durch die gesamten Bytes der Datei.

Obwohl es Dateiinhalt in den Speicher bringt, ist Joel Lord Antwort die Antwort für eine Node.js-Lösung. Sie können auch einen Blick auf readline module werfen.

+0

* Wissen, wie viele Zeilen diese Bytes haben, zählt Zeilenumbrüche * Exakt. Sie können auch "Zeilen zählen" als "Zeilenumbrüche zählen" betrachten (Zeilenumbrüche können für einige verwirrend sein), da dies eine "Zeile" definiert. Und um * Newline-Charaktere * zählen zu können, müssen Sie * alle * von ihnen finden. Was bedeutet, die * gesamte * Datei zu lesen. –

Verwandte Themen