Laden...

Einlesen einer sehr großen Textdatei

Erstellt von chrisrabe vor einem Jahr Letzter Beitrag vor einem Jahr 647 Views
C
chrisrabe Themenstarter:in
25 Beiträge seit 2014
vor einem Jahr
Einlesen einer sehr großen Textdatei

Hallo,

ich versucher erstmals mit C# eine mini WPF-Anwendung zu erstellen. Grundaufgabe soll es sein eine Textdatei zu öffnen und den Inhalt darzustellen.
Besonders daran ist, dass die Textdatei sehr groß ist (z.B. 980000 Zeilen mit je über 160 Zeichen). Sie beinhaltet Messwerte im Textformat und logging-Informationen.

Ich habe einige Versuche gemacht, jedoch scheinbar nicht die richtigen Methoden gefunden. Das Laden bzw. Darstellen des Dateiinhaltes dauert extrem lange (über eine Minute)
Aktuell lade ich die Datei so:


   private void Button_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            Nullable<bool> result = fd.ShowDialog();

            if (result == true)
            {
                if (File.Exists(fd.FileName))
                {
                    var run = new Run(File.ReadAllText(fd.FileName));
                    var p = new Paragraph(run);
                    var flowDocument = new FlowDocument(p);
                    documentViewer.Document = flowDocument;
                }
            }
        }

Ich habe auch Versuche mit einer Textbox gemacht, jedoch wird das dadurch nicht schneller.
Wenn ich vergleichsweise die selbe Datei mit Notepad++ offne, dann ist sie sofort dargestellt und ich kann darin scrollen. So würde ich mir das vorstellen.

Könnte mir jemand einen Tipp geben, wie es möglich ist so große Dateien zu öffnen?

Grüße
Christian

16.825 Beiträge seit 2008
vor einem Jahr

Du lädst die Datei vollständig in den Speicher, was immer lange dauert. Das hängt auch vom System ab, nicht maßgeblich von der Software.
Danach willst Du die Datei in ihrer vollen Größe in der UI darstellen, was ebenfalls Zeit kostet und die UI durch die Menge sehr langsam macht.
Auch Notepad++ kann nicht schneller laden, als es zum Beispiel die Festplatte hergibt.

Weil das in jeder Sprache, egal on C++ oder C#, eben aus Performance-Sicht schlecht ist, macht man das nicht.
Man lädt - zum Beispiel über einen Buffer - nur das, was man auch anzeigen muss: nimm daher statt File.ReadAll eben einen FileStream.
FileStream hat intern auch einen BufferedStream, der sich um das Memory Management der File Chunks kümmert, sodass Du nur noch mit Hilfe eines Streams lesen musst.

Der Source von Notepad++ ist ja offen, zur Not kann man also sich einfach den Source anschauen, wie Notepad++ das macht.

PS: in WPF verwendet man Datenbindung, keine Events. Programmiert leider nicht wie in WinForms.
[Artikel] MVVM und DataBinding
Verwendest Du das nicht, wirst Probleme bekommen. WPF is konzipiert, dass Du MVVM verwendest.

4.938 Beiträge seit 2008
vor einem Jahr

Hallo,

du solltest ein spezialisiertes Log Viewer Control benutzen, z.B. LogViewer2 (WPF).
Wenn ich mich nicht verrechnet habe, sollte deine Datei (ca. 146 MB) in ca. 2 Sekunden angezeigt werden (im Vergleich zu den 15s bei einer 1.2GB Datei im Test).

Ansonsten ist auch noch ein eigener Ansatz in der Antwort von Displaying large text files with WPF C# zu finden.

C
chrisrabe Themenstarter:in
25 Beiträge seit 2014
vor einem Jahr

Hallo Abt und Th69,

Ja, das WPF Konzept ist mir noch nicht so geläufig da ich bislang nur in WinForms gearbeitet habe. Dort hätte ich jetzt vermutlich versucht in einem separaten Thread die Daten zu laden statt in der ISR des ButtonLoad events. Die Darstellung wäre aber sicherlich auch nicht schneller geworden.

vielen Dank für die beiden Hinweise. Ich werde das so versuchen.

Grüße
Christian