Thread 80 Mio Zeilen einlesen
(24 answers)
Opened by FanClub at 2013-07-16 10:17 2013-07-16T08:41:12 FanClub Wenn ich es richtig verstanden habe, willst Du aus dem XML diejenigen <Produkt>...</Produkt>-Blöcke rausfiltern, deren Produkt_Nummer vorher schon einmal vorgekommen ist. Im obigen Beispiel würden also nur der erste und der letzte Produkt-Block wieder ausgegeben. Hier ein erster Ansatz mit Pseudo-Code Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 open(my $fh_in, '<', "input.xml") or die "... : $!"; open(my $fh_out, '>', "output.xml") or die "... : $!"; # Produkte, die schon ausgegeben wurden my %Produkt_nummer_gesehen; # lese immer einen kompletten Produktdatensatz ein local $/ = "</Produkt>"; while (my $prod = <$fh_in>) { my $pn = extract_produkt_nummer($prod); next if $Produkt_nummer_gesehen{$pn}++; print $fh_out, $prod; } Bei diesem Ansatz musst Du immer nur den Datensatz zu einem Produkt im Speicher halten plus einen Hash mit allen schon gelesenen Produktnummern. Bekommst du damit immer noch ein "Out of Memory"? Wenn der Datensatz für ein einzelnes Produkt so groß werden kann, dass er Deinen Speicher sprengt, die Produkt-Nummer aber immer relativ weit am Anfang des Prodiukt-Blocks steht, kann man noch etwas drehen, indem man den einzelen Produkt-Datensatz nicht auf einen Schlag einliest sondern nur bis man zur Produkt-Nummer kommt und entscheiden kann, ob man den Datensatz verwerfen oder ausgeben muss (und dann ggf. den Rest des Blocks zeilenweise lesen und gleich wieder ausgeben.) Allerdings wird dann die Programmstruktur komplexer. Wenn Du allerdings so viele und lange Produktnummern hast, dass der Hash zu groß wird, weiss ich auch nicht mehr weiter. Außer vielleicht noch eine Idee: Wenn die Produktnummern - wie in Deinem Beispiel - immer reine Zahlen sind, kann man vermutlich noch Speicherplatz sparen, in dem man int(extract_produkt_nummer($prod)) schreibt. |