Ergebnis 1 bis 4 von 4

C# Programmierung - ListView Export

  1. #1 Zitieren
    Demigod
    Registriert seit
    Dec 2007
    Beiträge
    9.255
    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 ist offline

  2. #2 Zitieren
    Provinzheld Avatar von Shuu
    Registriert seit
    Jun 2013
    Ort
    Night City
    Beiträge
    288
    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 ist offline

  3. #3 Zitieren
    Demigod
    Registriert seit
    Dec 2007
    Beiträge
    9.255
    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 ist offline Geändert von GRiva (28.02.2020 um 00:21 Uhr)

  4. #4 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.328
    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 ist offline Geändert von jabu (28.02.2020 um 06:30 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •