Results 1 to 4 of 4

C# Programmierung - ListView Export

  1. #1 Reply With Quote
    Halbgott GRiva's Avatar
    Join Date
    Dec 2007
    Posts
    9,256
    Hallo zusammen,

    Ich hatte jetzt kein passendes Unterforum gefunden und hoffe, dass es hier okay ist.

    Derzeit Versuche ich den Inhalt aus einer ListView in eine Datei zu exportieren.
    Der dazu verwendete Code:
    Code:
    foreach (ListViewItem listViewItem in listView1.Items)
                {
                    using (StreamWriter writer = new StreamWriter("your.txt"))
                    {
                        writer.WriteLine(listViewItem.Text);
                        foreach (ListViewItem subitem in listViewItem.SubItems)
                        {
                            writer.WriteLine(subitem.Text);
                        }
                    }
                }
    Leider gibt es ein Problem bei der Zweiten Foreach Loop.
    Es wird gemeldet, dass ListViewSubItem nicht in ListViewItem umgewandelt werden kann.

    Kann mir da jemand helfen? Leider ist es ziemlich zeitkritisch -.-

    MfG
    GRiva
    GRiva is offline

  2. #2 Reply With Quote
    Provinzheld Shuu's Avatar
    Join Date
    Jun 2013
    Location
    Citadel
    Posts
    284
    Probiers mal so:

    Code:
      foreach (ListViewItem listViewItem in listView1.Items)
                {
                    using (StreamWriter writer = new StreamWriter("your.txt"))
                    {
                        writer.WriteLine(listViewItem.Text);
                        foreach (ListViewItem.ListViewSubItem subitem in listViewItem.SubItems)
                        {
                            writer.WriteLine(subitem.Text);
                        }
                    }
                }
    Shuu is offline

  3. #3 Reply With Quote
    Halbgott GRiva's Avatar
    Join Date
    Dec 2007
    Posts
    9,256
    Okay, vielen Dank, das hat geklappt. Jetzt stehe ich vor einem anderen Problem.
    Scheinbar wird hierdurch immer nur eine Zeile der ListView in die Datei eingefügt.
    Das Programm startet, ließt die Datei aus. Füge ich dann eine weitere Zeile hinzu und speicher das ganze wie unten angegeben,
    ist lediglich die letzte Zeile der ListView in der Datei enthalten....
    Code:
    if (File.Exists(@"contents.txt"))
                {
                    System.IO.File.WriteAllText(@"contents.txt", String.Empty);
                    foreach (ListViewItem listViewItem in listView1.Items)
                    {
                        using (StreamWriter writer = new StreamWriter("contents.txt"))
                        {
                            writer.WriteLine(listViewItem.Text);
    
                            foreach (ListViewItem.ListViewSubItem subitem in listViewItem.SubItems)
                            {
                                writer.WriteLine(subitem.Text);
                            }
                        }
                    }
    GRiva is offline Last edited by GRiva; 28.02.2020 at 00:21.

  4. #4 Reply With Quote
    Haltet Abstand! besser>2m  jabu's Avatar
    Join Date
    Jul 2011
    Posts
    4,900
    Innerhalb der äußeren Schleife erzeugt dein Code bei jedem Durchgang per new StreamWriter("contents.txt") ein neues StreamWriter-Objekt, wobei folglich jedes Mal die angegebene Datei erneut geöffnet, beschrieben und geschlossen wird. Obwohl das Vorgehen unnötig umständlich ist, sollte es funktionieren, falls einer der StreamWriter-Konstruktoren mit optionalem Anfügemodus gewählt ist, z.B. dieser, wodurch sich folgender Konstruktoraufruf ergeben würde: new StreamWriter("contents.txt", true). Der bisherige Konstruktor wählt den Überschreibmodus aus, weswegen der vorherige Dateiinhalt verloren ist (was dem von dir festgestellten Symptom entsprechen sollte). Aber diese Lösung wäre noch ziemlich ineffizient.

    Weil es eben ineffizient ist, bei jedem äußeren Schleifendurchgang die Datei erneut zu öffnen und zu schließen, sollte es sinnvoller sein, den using-Block die äußere Schleife umschließen zu lassen bzw. die äußere Schleife innerhalb des using-Blocks anzuordnen, um den Stream wiederzuverwenden. Dann stellt sich das Problem des Überschreibens in dieser Form erst gar nicht, sodass der bisherige Anfügemodus in diesem Kontext korrekt wäre und sodass man normalerweise (es sei denn, du wüsstest einen guten Grund, der dagegen spricht) auf das umständliche explizite Leeren der Datei per Überschreiben mittels System.IO.File.WriteAllText(@"contents.txt", String.Empty) verzichten können sollte, sodass die entsprechende Zeile obsolet wäre. Natürlich ist der Anfügemodus dann nicht mehr sinnvoll, sondern der bisherige Überschreibmodus, weil dann eben genau einmal am Anfang überschrieben wird. Diese seltsam unelegante Zeile scheint mir extra für die erste (umständlichere) Lösung vorgesehen zu sein.

    Solange einem der RAM nicht ausgeht (sollte er hier normalerweise nicht so leicht, kann ich aber nicht wissen), könnte man alles an einen String anhängen (Zeilenumbruch nicht vergessen) und den in einem Rutsch schreiben, was der Ausführungsgeschwindigkeit zugute kommen könnte, aber so sicher ist ein Verbesserungspotenzial bei guter interner Implementierung eines Puffers nicht. Dazu sollte sich auch das bereits gezeigte System.IO.File.WriteAllText verwenden lassen, was vom Prinzip her nochmal einen Geschwindigkeitsschub ergeben könnte. Ob sich der real ergibt, habe ich jedoch nicht überprüft.

    Das wären also drei alternative Lösungen. Wegen ihrer relativen Robustheit würde ich, solange keine guten Gründe für die dritte sprechen (z.B. Messergebnisse), die zweite Lösung favorisieren. Aber das alles hier schreibe ich ohne Gewähr (zudem ist C# nicht meine Hauptsprache), es ist ungetestet, und ich befinde mich derzeit beinahe im Halbschlaf. Code schreibe ich absichtlich nicht hin, um den Lerneffekt nicht ganz zu verderben (sieht für mich nach einer bewusst gestellten Aufgabe aus).

    Vielleicht möchtest du dir auch dieses Beispiel zum Schreiben von Text in eine Datei, welches das allgemeine Konzept etwas ausführlicher veranschaulicht, angucken. Auch diese Erklärung zur using-Anweisung könnte hilfreich sein. Es geht beim using-Block im Wesentlichen darum, angeforderte Ressourcen (hier insbes. vom Betriebssystem bereitgestellte) beim Verlassen des Blocks automatisch freizugeben (Datei schließen, File-Handle freigeben). Ansonsten ginge das (explizit) per Dispose-Methode. Aber davon will man möglichst weg, weil in der Praxis schwer sicherzustellen ist, dass dieses auf allen möglichen Pfaden geschieht. Insbesondere bei Exceptions sowie bei nachträglich eingefügten return-Pfaden bleibt das oftmals aus. Außerdem kann Dispose im finally-Zweig u.U. die Softwarearchitektur ungünstig beeinflussen oder auf eine ungünstige Weise festlegen.

    Ich verschiebe dieses Thema in das Programmierforum, Grüße aus dem Softwareforum!
    jabu is offline Last edited by jabu; 28.02.2020 at 06:30.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •