Probleme mit dem speichern von .XML-Dateien

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Probleme mit dem speichern von .XML-Dateien

    Hallo liebe VBP-Community,



    undzwar wollte ich so etwas wie einen alternative Explorer programmieren da der von Windows ja manchmal spinnt, ich hatte auch vor diesen Explorer hier im VBP zu veröffentlichen aber nur wenn ihr mir helft den sosnt werde ich das nie packen. Ich wollte in meinen Explorer direkt in die Version 1.0 Beta einen XML-basierten Verlauf integrieren der zwar im moment einigermasen funktioniert aber da dieser Tab-basiert ist (MDI-Tabcontrol) ist das ganze ein bisschen komplexer. Bisher habe ich es so gemacht das in der Main_Form ein unsichbares ListView ist in das alles aufgerufenen Pfade gespeichert werden bei dem Duplikate durch eine For-Each-Schleife gefiltert und gelöscht werden die wie folgt aussieht :

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function RemoveDuplicates(ByVal lstView As ListView) As Boolean
    2. Dim itemI As ListViewItem
    3. Dim itemJ As ListViewItem
    4. Dim progress As Integer
    5. Dim count As Integer
    6. For i As Integer = lstView.Items.Count - 1 To 0 Step -1
    7. itemI = lstView.Items(i)
    8. progress = progress + 1
    9. For z As Integer = i + 1 To lstView.Items.Count - 1 Step 1
    10. itemJ = lstView.Items(z)
    11. If itemI.SubItems(1).Text = itemJ.SubItems(1).Text Then
    12. lstView.Items.Remove(itemJ)
    13. count = count + 1
    14. Exit For
    15. End If
    16. Next z
    17. Next (i)
    18. End Function


    Mein Explorer speichert 2 Sachen im Verlauf, einmal den Zeitpunkt und einmal den Ort... falls nun also ein Duplikat beim Ort gefunden wird wird dieses einfach entfernt. Nun kommt aber das eigentlich Problem undzwar habe ich nicht immer und immer und immer wieder Lust den ganzen Verlauf durch eine lange For-Each-Schleife beim navigieren zwischen den Pfaden komplett neu zu schreiben und als .XML abzuspeichern da dies sehr unsauber und Ressourcenfressen ist. Einfach gesagt ist es aktuell so das sobald man in einen anderen Pfad wechselt der Pfad in dem unsichtbaren ListView in der Main_Form gespeichert wird danach auf Duplikate geprüft würd und anschliessend werden alle Items im ListView in einer neuen .XML gespeicht bei der das gesamt ListView nochmal neu geschrieben wird was sehr unschön ist... also kurz und einfach ist es immer wieder : In ListView speichern, auf Duplikat prüfen, ListView in komplett neue .XML schreiben.



    Speichern tu ich übrigens so :

    Spoiler anzeigen


    VB.NET-Quellcode

    1. Dim wtrXML As New XmlTextWriter(My.Application.Info.DirectoryPath & "\History.xml", System.Text.Encoding.UTF8)
    2. With wtrXML
    3. .Formatting = Formatting.Indented
    4. .WriteStartDocument()
    5. .WriteStartElement("WebSites")
    6. Dim objListViewItem As New ListViewItem
    7. For Each objListViewItem In ListView1.Items
    8. .WriteStartElement("WebSite")
    9. .WriteElementString("Name", objListViewItem.Text)
    10. .WriteElementString("URL", objListViewItem.SubItems(1).Text)
    11. .WriteElementString("Time", objListViewItem.SubItems(2).Text)
    12. .WriteEndElement()
    13. Next
    14. .WriteEndElement()
    15. .WriteEndDocument()
    16. .Flush()
    17. .Close()
    18. End With




    Gibt es keine bessere Methode? Muss ich echt bei jedem Pfad-Wechsel das gesamte Dokument nochmal neu schreiben?


    MfG InputOutput
    Schreibt dir doch eine Klasse die das Verwaltet

    VB.NET-Quellcode

    1. Public Class Toast
    2. Public Property Time As DateTime
    3. Public Property Path As String
    4. End Class

    Und Serialisier das.

    VB.NET-Quellcode

    1. Public Sub XMLSerialize(Of T)(ByVal Obj As Object, ByVal FileName As String)
    2. Using FS As New FileStream(FileName, FileMode.Create)
    3. Dim XML As New XmlSerializer(GetType(T))
    4. XML.Serialize(FS, Obj)
    5. End Using
    6. End Sub
    7. Public Function XMLDeSerialize(Of T)(ByVal FileName As String) As Object
    8. Using FS As New FileStream(FileName, FileMode.Open)
    9. Dim XML As New XmlSerializer(GetType(T))
    10. Return XML.Deserialize(FS)
    11. End Using
    12. End Function

    Aufruf:

    VB.NET-Quellcode

    1. Dim toast As Toast = XMLDeSerialize(Of Toast)("Brot.xml")
    2. 'und
    3. XMLSerialize(Of Toast)(toast, "Brot_2.xml")
    Wirklich besser ist die Methode ja auch nicht da ich das so sehe das dort für ein neuen Pfad im ListView der ganze Verlauf nochmal neu angelegt werden muss in einer .XML :/ Ich will halt nicht immer wieder die ganze XML-Datei neu anlegen müssen durch ver****** For-each Schleifen nur um ein Pfad mehr im Verlauf zu haben )=

    //Edit : Sorry das ich es so schwer mache aber ich hab halt was gegen For-Each und vor allem wenn es immer und immer wieder ist^^
    Okay.
    Folgendes:

    VB.NET-Quellcode

    1. Dim listevonVerlauf As New List(Of Toast)

    Schonmal mit Listen gearbeitet?
    Dann sollte dir das helfen:

    VB.NET-Quellcode

    1. XMLSerialize(Of List(Of Toast))(listevonVerlauf, "Datei")

    Aber um neuschreiben wirst du nicht herumkommen.
    Nein, mit List habe ich noch nie wirklich gearbeitet.

    Programmierer eher gelegentlich und wenn dann auch nur nach Bedarf und das seit knappt 1-2 Jahren...

    Wie sieht es den mit System.IO aus? Also mit den guten-alten ini's, gibt es da irgendwie eine bessere Methode?
    Der IO-Stammbaum hat ja schon bei File. viele Namespace's
    Also, du kannst dir entweder deine eigene Datei zusammenbasteln oder alles machen lassen (Serialisierung). -> Neuschreiben tust du immer.
    INI an sich kannste vergessen, da du dort nicht weißt, wie viele Einträge wirklich existieren.

    Mit der Serialisierung ist alles relativ einfach:
    Öffnen von Datei:

    VB.NET-Quellcode

    1. Liste.Add(Pfad)
    2. XMLSerialize(Of List(Of Klasse))(Liste, Datei)

    Mehr brauchste nicht machen.
    Wenn du nun den Verlauf öffnen willst:

    VB.NET-Quellcode

    1. Liste = CType(XMLDeSerialize(Of List(Of Klasse))(Datei), List(Of Klasse)
    Ich habe gerade mal überlegt also bei My-Setting wüsste ich es aber *würg* und was doch E-I-G-E-N-T-L-I-C-H auch gehen müsste ist das man mit dem XML-Reader das ganz irgendwie so ausliesst das man automatisch im Dokument nach ganz unten springt und dort dann einfach die Pfad-Adresse anhängt den andauerndes neu schreiben und dann noch mit For-Each ist in jeder Hinsicht schlecht!

    //Edit : Kann man nicht auch irgendwie im ListView übrprüfen ob der Pfad schon vorhanden ist? Dann könnte man sich den Dress zum größten Teil sparen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „InputOutput“ ()

    InputOutput schrieb:

    Muss ich echt bei jedem Pfad-Wechsel das gesamte Dokument nochmal neu schreiben?
    Das frag ich dich, ob und wozu das gut ist.
    Ich zb. schreibe nur dann Dateien, wenn der User auf Save gedrückt hat, oder wenn die Anwendung schließt.

    Annere Frage: Diese Massen sinnloser Leerzeilen in deim Code - ist das Absicht oder ein Forum-Bug? Weil wennde den VB-Tag richtig benutzen tust, dann - jo - sind die Methoden doch viel besser als Einheit erkennbar - und kann man ühaupt viel mehr sehen (doppelt soviel, um genau zu sein)

    VB.NET-Quellcode

    1. Dim wtrXML As New XmlTextWriter(My.Application.Info.DirectoryPath & "\History.xml", System.Text.Encoding.UTF8)
    2. With wtrXML
    3. .Formatting = Formatting.Indented
    4. .WriteStartDocument()
    5. .WriteStartElement("WebSites")
    6. Dim objListViewItem As New ListViewItem
    7. For Each objListViewItem In ListView1.Items
    8. .WriteStartElement("WebSite")
    9. .WriteElementString("Name", objListViewItem.Text)
    10. .WriteElementString("URL", objListViewItem.SubItems(1).Text)
    11. .WriteElementString("Time", objListViewItem.SubItems(2).Text)
    12. .WriteEndElement()
    13. Next
    14. .WriteEndElement()
    15. .WriteEndDocument()
    16. .Flush()
    17. .Close()
    18. End With
    Ups - das gibts ja noch nichtmal den Methoden-Kopf und Fuß!

    Bis hierher erstmal - üblicherweise wird von meinen Gedanken immer nur einer aufgefasst, und dieser Post enthält jetzt schon 2