Autor Beitrag
elchgesicht
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 28.09.10 20:04 
Hallo zusammen,
erst mal als Basisinfo: ich bin neu unterwegs mit c#, programmiere aber seit Jahren in diversen anderen Sprachen. Nun hab ich folgendes Problem: ich muss ein sehr großes Logfile parsen, ca 12 Mio Zeilen.
Nun verwende ich die Klasse StreamReader. Bei kleinen Testdateien läuft alles super. Bei den großen realen Exemplaren ist allerdings nach ca 6,7 Mio Zeilen Schluss.
Fehler: Array Index out of range.
Das Problem ist, es muss ein klasseninterner Index sein, der da voll läuft, da ich selber keinen Index oder ein Array verwende.

Frage: Kennt jemand das Problem?
Frage: Gibt es eine einfache Möglichkeit, eine Datei wirklich Zeilenweise zu lesen, ohne dass ein Puffer (außer einer meiner Wahl) beschrieben wird. ?
Ich bin dankbar für alle Tipps.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
  private void readFile()
            {
                string line = "";
                    if ((char)this.stream.Peek()=='T')
                    {
                        this.stream.ReadLine();
                    }

                    uint linecounter=0;
                    while((line = this.stream.ReadLine())!=null)
                    {
                        linecounter++;

//das ist ein Versuch das Problem zu umgehen, aber es hilft nichts
                        if (linecounter %100000 == 0)
                        {
                            this.stream.DiscardBufferedData();
                            Console.WriteLine(linecounter);
                        }
                        if (!(line.StartsWith("\t")) && (Char.IsDigit(line[0])))
                        {

                            this.data.numberofcalls++;
                        }
                    }
                    this.stream.Dispose();
                    this.stream.Close();
              }
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 28.09.10 21:30 
:welcome: in der EE!

12 Millionen Zeilen :shock: . Ich weiß nicht, warum sich der StreamReader dort verschluckt (kompletter Stack Trace wäre schön :) ), aber bei solchen Datenmengen sollte ReadLine doch sowieso einen derartigen Flaschenhals darstellen, dass eigentlich nur in Frage kommt, den Stream direkt anzusprechen. Oder nicht?

_________________
>λ=
elchgesicht Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 28.09.10 21:56 
Vielen Dank für die Antwort.
In die Richtung habe ich auch schon gedacht, aber leider nichts gefunden was mich weiterbringt. Hättest du vielleicht einen Hinweis nach was oder wo ich suchen könnte für ein Beispiel?
Ich dachte eigentlich, dass ReadLine halt eine Zeile ließt und den Puffer dann bei der nächsten überschreibt. Aber irgendwas scheint intern mitzulaufen, dass es nicht funktioniert.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 28.09.10 22:12 
Nunja, einen Buffer in der gewünschten Größe reservieren und Stream.Read aufrufen. Wie es der StreamReader intern auch macht.
Gut, sollte es nicht um ASCII gehen, wird das Deokdieren dann noch einmal spannend ;) .

_________________
>λ=

Für diesen Beitrag haben gedankt: elchgesicht
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 30.09.10 20:17 
user profile iconelchgesicht hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden C#-Quelltext
 
20:
21:
/* ... */
if (!(line.StartsWith("\t")) && (Char.IsDigit(line[0])))
    /* ... */

Bist du dir sicher, dass in jeder Zeile mindestens ein Zeichen steht? Andernfalls würde der Zugriff auf das erste Zeichen eine Exception werfen.

Außerdem denke ich, dass die linke Bedingung sinnlos ist, denn wenn das erste Zeichen eine Ziffer ist, kann es kein Tabulator sein...
elchgesicht Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 30.09.10 21:06 
Diese Zeile war noch Teil der "Lesestudie" und wird definitiv noch geändert. Gestern habe ich mit einem anderen Tool (das neue soll dieses ersetzen, leider) eine Datei parsen müssen mit 21 GB Größe. Da werde ich noch jede Nanosekunde raus holen müssen, sonst dauert das geparse später mal ewig.
Das Ganze wird auch noch eine nette "Performancestudie" für .NET. Mal sehen was raus kommt.
Trotzdem danke für den Hinweis.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 30.09.10 22:53 
user profile iconelchgesicht hat folgendes geschrieben Zum zitierten Posting springen:
Das Ganze wird auch noch eine nette "Performancestudie" für .NET. Mal sehen was raus kommt.
Das Einlesen einer Datei sollte ja wohl in allen Sprachen gleich langsam sein ;) . Bei ganz harten Fällen kann das Parsen auch in einen zweiten Thread verlagert werden.

_________________
>λ=