# Teile großer XML Datei effektiv einlesen



## 00Stan (17. Juni 2011)

*Teile großer Datei effektiv einlesen*

Hallo Community,
ich hab da ein Problem, bei dem ich eure Hilfe benötige. Ich soll ein Programm schreiben, welches  bestimmte Teile einer großen XML-Datei (2GB und größer) möglichst schnell einliest.
Gegeben ist die Anfangs- und die Endzeile des Ausschnitts und die Datei selbst natürlich, mehr nicht. 

Ich habe es zunächst mit dem Scanner probiert, für eine 2GB große Datei (ca. 43.000.000 Zeilen) hat er im Schnitt 80s gebraucht, ist also viel zu langsam(für die Tests habe ich immer den schlechtesten Fall angenommen: Der  gesuchte Ausschnitt besteht aus den letzten 5 Zeilen der Datei. Danach kam der BufferedReader zum Einsatz:


```
public void read( long firstLine, long lastLine ) {
        long lineCount = 0;
        String line;
        StringBuffer buffer = new StringBuffer();
        try {
            BufferedReader bufferedReader = new BufferedReader( new FileReader( "C:\\largefile.xml" ));
            try {
                while ( lineCount < lastLine && ( line = bufferedReader.readLine() ) != null ) {
                    if ( lineCount >= firstLine ) {
                        buffer.append( line + "\r\n" );
                    }
                    lineCount++;
                }
            } finally {
                bufferedReader.close();
            }
        } catch ( IOException e ) {
            e.printStackTrace();
        }
        System.out.println( buffer.toString() );
    }
```
Diese Methode braucht auf meinem Rechner im Schnitt ca. 30s, schon schneller als der Scanner, aber trotzdem zu langsam, weil die Dateien auch 10GB groß sein können. 

Leider habe ich im Internet nicht viel über das performante Einlesen der Dateien gefunden. Hier im Forum habe ich über die Klasse RandomAccessFile gelesen, ist zwar interessant, für mich aber unbrauchbar, ich kenne nur die Zeilennummer.

Vielleicht kennt hier jemand andere Möglichkeiten, die mein Problem schneller lösen können. 

Ich hoffe, ihr könnt mir helfen und bedanke mich schon im Voraus!

Gruß
Stan


P.S.: Falls es relevant sein sollte, mein Rechner: 

Win 7 64Bit
3 GB RAM
intel core 2 @ 2,4GHz


----------



## Thomas Darimont (17. Juni 2011)

Hallo,

du redest immer von viel zu langsam... wie schnell muss es denn sein?
Wie ist deine XML Datei denn aufgebaut? Könnte man die Datei in logische Blöcke zerlegen?


> Leider habe ich im Internet nicht viel über das performante Einlesen der Dateien gefunden. Hier im Forum habe ich über die Klasse RandomAccessFile gelesen, ist zwar interessant, für mich aber unbrauchbar, ich kenne nur die Zeilennummer.


Nicht so schnell... wenn deine XML Dokumente relativ homogen und zeilenweise aufgebaut sind könntest du durch Sampling der ersten X Zeilen deines Dokuments eine Statistik über die durchschnittliche Zeilenlänge (in bytes) berechnen. Damit könntest du mit der Formel Zeile * durchschnittlicheZeilenGrößeInBytes ein Offset bestimmen das zumindest in die Nähe deiner Zielzeile liegt. Von dort an könntest du dann nur noch den nachfolgenden Abschnitt genauer untersuchen... das Verfahren könnte man sogar öfters wiederholen wenn man "ungefähr" wüsste wie viele "Zeilen" / Elemente man von der Zielzeile entfernt ist... ähnlich wie das Newton Verfahren zur Nullstellenermittlung...




Zur Verarbeitung großer XML Dokumente bieten sich StAX basierte XML Parser an:
http://woodstox.codehaus.org/Documentation
http://stax.codehaus.org/Home

Gruß Tom


----------



## 00Stan (17. Juni 2011)

Hallo Tom,
danke erstmal für die schnelle Antwort!
Geschwindigkeit: wenn möglich unter 10s. 

Über eine statistische Auswertung der ersten Zeilen habe ich auch schon nachtgedacht, 
leider bringt es nicht viel. Denn, wie die Datei aufgebaut ist, weiß ich leider nicht. Ja, ich habe das Thema falsch benannt, sorry für die Verwirrung. Meine Aufgabe lautet eine Datei auszulesen, ob es eine XML- oder CSV-Datei ist, sollte keine Rolle spielen. Außerdem reicht der ungefähre Sprung leider nicht aus, wenn ich irgendwo mitten in die Datei reinspringe, kann ich nicht garantieren, dass ich da auch richtig bin. Ich muss genau die Zeilen zurückgeben, die gefordert werden, keine mehr und keine weniger.


----------

