Große Textdateien in Echtzeit parsen (Java)

7

Ich bin an der Analyse einer ziemlich großen Textdatei in Java interessiert (1.6.x) und habe mich gefragt, welche Vorgehensweise (n) als Best Practice angesehen wird?

Die Datei wird wahrscheinlich etwa 1 MB groß sein und aus tausenden von Einträgen bestehen, die den Zeilen

entsprechen %Vor%

usw.

Mein erster Instinkt besteht darin, reguläre Ausdrücke zu verwenden, aber ich habe keine Erfahrung mit Java in einer Produktionsumgebung und bin daher nicht sicher, wie mächtig die java.util.regex-Klassen sind.

Um ein wenig Klarheit zu schaffen, wird meine Anwendung eine Web-App (JSP) sein, die die fragliche Datei analysiert und die verschiedenen Werte anzeigt, die sie abruft. Es gibt immer nur die eine Datei, die geparst wird (sie befindet sich in einem 3rd-Party-Verzeichnis auf dem Host).

Die App wird relativ wenig genutzt werden (vielleicht nur eine Handvoll Benutzer, die sie mehrmals am Tag benutzen), aber es ist wichtig, dass die Informationen bei ihrer Verwendung so schnell wie möglich abgerufen werden.

Gibt es auch Vorsichtsmaßnahmen, um die Datei bei jedem Parsing in den Speicher zu laden?

Kann mir jemand eine Herangehensweise empfehlen?

Danke

    
Christopher McAtackney 23.04.2009, 11:23
quelle

9 Antworten

8

Wenn es etwa 1 MB und buchstäblich in dem von Ihnen angegebenen Format ist, dann klingt es so, als würden Sie Dinge übersteuern.

Wenn Ihr Server kein ZX Spectrum oder etwas anderes ist, verwenden Sie einfach reguläre Ausdrücke, um die Daten zu analysieren, die Daten in eine Hash-Map zu packen (und dort zu behalten), und sorgen Sie sich nicht darum. Es dauert ein paar Megabyte im Speicher, aber was dann ...?

Update: nur um Ihnen eine konkrete Vorstellung von der Leistung zu geben, einige Messungen, die ich von der Leistung von String.split () (die reguläre Ausdrücke verwendet) zeigen, dass es auf einem 2-GHz-Computer Millisekunden dauert, 10.000 100-Zeichenfolgen zu teilen (mit anderen Worten, etwa 1 Megabyte Daten - tatsächlich näher 2 MB in reinem Volumen von Bytes, da Strings 2 Bytes pro Char sind). Offensichtlich, das ist nicht ganz die Operation, die Sie durchführen, aber Sie verstehen, was ich meine: Die Dinge sind nicht so schlecht ...

    
Neil Coffey 23.04.2009, 12:59
quelle
5

Wenn es sich um eine richtige Grammatik handelt, verwenden Sie einen Parser-Builder wie das GOLD-Parsing-System . Auf diese Weise können Sie das Format angeben und einen effizienten Parser verwenden, um die benötigten Tokens zu erhalten, wodurch die Fehlerbehandlung nahezu kostenlos erfolgt.

    
Lucero 23.04.2009 11:26
quelle
4

Ich frage mich, warum dies nicht in XML ist und Sie dann die verfügbaren XML-Tools nutzen könnten. Ich denke besonders an SAX, in diesem Fall könnten Sie dies leicht analysieren / verarbeiten, ohne alles im Gedächtnis zu behalten.

Kannst du das also in XML umwandeln?

Wenn Sie das nicht können und einen Parser benötigen, sehen Sie sich JavaCC

an     
Brian Agnew 23.04.2009 11:26
quelle
3

Verwenden Sie die Scanner-Klasse und bearbeiten Sie Ihre Datei jeweils Zeile für Zeile. Ich bin mir nicht sicher, warum Sie Regex erwähnt haben. Regex ist fast nie die richtige Antwort auf eine Parsing-Frage wegen der Mehrdeutigkeit und des Fehlens von symmantischen Contorl darüber, was in welchem ​​Kontext passiert.

    
mP. 23.04.2009 11:33
quelle
2

Sie können den Parser-Generator Antlr verwenden, um einen Parser zu erstellen, der Ihre Dateien analysieren kann.

    
paweloque 23.04.2009 11:47
quelle
1

Beantworten Sie die Frage zum Parsen nicht ... aber Sie könnten die Dateien parsen und statische Seiten erzeugen, sobald neue Dateien eintreffen. Sie hätten also keine Performance-Probleme ... (Und ich denke 1 MB ist keine große Datei, also können Sie sie in den Speicher laden, solange Sie nicht zu viele Dateien gleichzeitig laden ...)

    
pgras 23.04.2009 12:03
quelle
1

Dies scheint ein einfaches Dateiformat zu sein, daher sollten Sie einen Recursive Descent Parser in Erwägung ziehen. Im Vergleich zu JavaCC und Antlr besteht die Vorteile darin, dass Sie ein paar einfache Methoden schreiben können, die benötigten Daten erhalten und keinen Parser-Generator-Formalismus lernen müssen. Seine Nachteile - es kann weniger effizient sein. Ein rekursiver Descent-Parser ist prinzipiell stärker als reguläre Ausdrücke. Wenn Sie eine Grammatik für diesen Dateityp erstellen können, wird es Ihnen für die von Ihnen gewählte Lösung dienen.

    
Yuval F 23.04.2009 12:25
quelle
1

Wenn es die Einschränkungen von Java Regexes sind, über die Sie sich wundern, machen Sie sich keine Sorgen darüber. Vorausgesetzt, Sie sind einigermaßen kompetent in der Erstellung von Regexes, sollte die Performance kein Problem sein. Das Feature-Set ist auch zufriedenstellend reich - einschließlich meiner Lieblings-, Possessiv-Quantoren .

    
Alan Moore 23.04.2009 13:23
quelle
1

Die andere Lösung besteht darin, eine Form der Vorverarbeitung durchzuführen (offline oder als Cron-Job), die eine sehr optimierte Datenstruktur erzeugt, die dann verwendet wird, um die vielen Web-Anfragen zu bedienen (ohne die Datei analysieren zu müssen).

Wenn man jedoch das fragliche Szenario betrachtet, scheint das nicht nötig zu sein.

    
Chii 23.04.2009 14:26
quelle

Tags und Links