Datei laden, Text ersetzen und Datei wieder speichern

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von TRiViUM.

    Datei laden, Text ersetzen und Datei wieder speichern

    Hallo Leute,

    Ich habe zwar schon in diesem Forum einen änlichen Beitrag gefunden und auch getestet, aber anscheind will es wohl nicht richtig.

    Ich habe ein Programm, dass eine Items.txt läd. Formatierung der Datei:

    Äpfel$2
    Holz$17
    Gold$0

    usw.

    EDIT:
    Das Programm läd diese Datei und splittet dann jede Zeile in 2 Stücke mit folgendem Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim Lines() As String = System.IO.File.ReadAllLines(Application.StartupPath & "\Items.txt")
    2. For Each Line As String In Lines
    3. Dim Split() As String = Line.Split(CChar("$"))
    4. 'Hier z.B. die Äpfel-Anzahl 2 mit der Zahl 7 ersetzen
    5. If Split(0) = "Äpfel" and Split(1) = "2" then
    6. Split(1) = Split(1).replace(Split(1), "7")
    7. End If
    8. next


    Nur jetzt noch die Item.txt mit dem ersetzten Ihnalt wieder zu speichern, bekomm ich auch nicht hin, weil ich nicht weiß, wie ich die geänderte Datei ansprechen kann...

    Dies ist die Lösung:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim sFile = Application.StartupPath & "\Items.txt"
    3. Dim lines() As String = File.ReadAllLines(sFile)
    4. Using writer = New StreamWriter(sFile, False)
    5. For Each line In lines
    6. Dim data = line.Split("$"c)
    7. If data(0) = "Äpfel" AndAlso data(1) = "2" Then data(1) = TextBox_NeuesValue.Text
    8. writer.WriteLine(String.Join("$", data))
    9. Next
    10. End Using
    11. End Sub


    Ist mir da zu helfen?

    DANKE! :)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TRiViUM“ ()

    Leg dir zuerst mal ne ordentliche Datenstruktur an. Sinnvoll wäre in dem Fall z.B. eine Klasse, die einen Namen und eine Anzahl enthält. Dann liest du dir den Inhalt als erstes in eine List(Of <deineKlasse>) ein, in der du alles ändern kannst, was du willst. Aus dieser Liste kannst du dann später ganz einfach die alte Datei überschreiben.
    Am besten ist du machsts mit nem StreamWriter. Erstelle dir dafür eine FileInfo-Instanz mit dem Pfad zur INI, hohl dir den FileStream mit Open und übergib diesen dem StreamWriter. Dann kannst du pro Instanz der Entry-Klasse mit WriteLine einen Eintrag erstellen.
    Es sollte wesentlich einfacher gehen.
    Wenn Du weißt, wie Du den Inhalt Deiner Zeilen manipulierst, solltest Du die bearbeiteten Zeilen sofort abspeichern:

    VB.NET-Quellcode

    1. IO.File.AppendAllText(DEINE_DATEI, DIE_NEUE_ZEILE & Environment.NewLine)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Es sollte wesentlich einfacher gehen.
    das bezweifel ich sehr, jdfs. File.AppendAllText() ist doch wohl wieder deine berühmte C&P-Bremse, um den TE zu verwirren?

    Wo ichs grad ausgezeichnet fände, wenn der TE sich mit dem objektorientierten Instrumentarium für Dateizugriffe: FileInfo, StreamWriter, evtl. FileStream bekannt machen würde, statt blindlings diese komischen Anti-OOP-"Abkürzungen" (die meist nichtmal kürzer sind) zu laufen.

    ErfinderDesRades schrieb:

    ist doch wohl wieder deine berühmte C&P-Bremse
    Wieso?
    Zeilen rein, bearbeiten, neu zusammensetzen, weg und vergessen.
    Und nicht aufräumen müssen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also ich hab das jetzt ein bisschen experimentiert, und folgende Lösung bekommen:

    VB.NET-Quellcode

    1. 'Benötigter Import
    2. Imports System.Text
    3. '[...]
    4. Dim ItemsFileNEW as new StringBuilder()
    5. Dim ItemsFileOLD() as String = System.IO.File.ReadAllLines(Application.StartupPath & "\Items.txt")
    6. For Each Item in ItemsFileOLD
    7. Dim Split() as String = Item.Split(CChar("$"))
    8. If Split(0) = "Äpfel" and Split(1) = "2" Then
    9. Item = Item.Replace(Split(1), TextBox_NeuesValue.Text)
    10. Else
    11. End If
    12. ItemsFileNEW.Append(String.Join("$", Item.ToString)))
    13. ItemsFileNEU.Append(Environment.NewLine)
    14. Next
    15. My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\Items.txt", ItemsFileNEW.ToString, False)


    So funzt es.

    EDIT:

    FAST!

    Habe grad bemerkt, dass er, weil ich anstatt "Äpfel" aber "2" drin stehn hatte, aus der Zeile dann (Wenn die zu ersetzende Zahl z.B. 5 ist) "5$5" gemacht hat, obwohl ich ihm eig. sage, dass er nur Split(1) erstzen soll...Denkfehler?!

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „TRiViUM“ ()

    Kannst grad nochmal bitte den zu testenden Code posten?
    damit ich mir schon mal bis morgen varianten überlegen kann, falls er nicht sofort funzt :D
    Aber vom prinzip ist der neue und der alte doch quasie identisch oder?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TRiViUM“ ()

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim sFile = Application.StartupPath & "\Items.txt"
    3. Dim lines() As String = File.ReadAllLines(sFile)
    4. Using writer = New StreamWriter(sFile, False)
    5. For Each line In lines
    6. Dim data = line.Split("$"c)
    7. If data(0) = "Äpfel" AndAlso data(1) = "2" Then data(1) = TextBox_NeuesValue.Text
    8. writer.WriteLine(String.Join("$", data))
    9. Next
    10. End Using
    11. End Sub
    ReadAllLines ist hier ausnahmsweise zweckmäßig, weil du dieselbe Datei schreiben willst, die du auch ausliest, und gleichzeitig Lesen und überschreiben läuft nicht.
    ansonsten straightforward:
    Die Zeilen werden als Datensatz aufgefasst und in ihre Daten gesplittet. Gegebenenfalls wird data(1) ausgetauscht.
    Der Writer schreibt die wieder zum Datensatz zusammengesetzte Zeile dann weg und feddich.

    Beachte auch die Notation des Chars beim Splitten - von CChar("$") kriegich Kopfweh ;)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ich danke dir, funktioniert soweit auch ganz gut.

    Doch stehe ich jetzt noch vor dem Problem, wie du es schon beschrieben hast:

    Weil ich dieselbe Datei schreiben will, die ich auch auslese, und gleichzeitig Lesen und überschreiben läuft nicht.

    Gabs nicht so nen Befehl, die Items.txt wieder freizugeben?

    Also zum Verständnis, innerhalb der For Each-Schleife wird die Items.txt ja vom Programm verwendet.

    Wenn das Programm die zu ändernde Zeile gefunden hat, ändert es den Wert duch die entsprechende Eingabe, aber nur im Programm oder?

    Weil wenn ich danach die txt öffne, ist sie wie vorher, also ohne änderung.

    TRiViUM schrieb:

    Ich danke dir, funktioniert soweit auch ganz gut.
    Doch stehe ich jetzt noch vor dem Problem, wie du es schon beschrieben hast:
    Weil ich dieselbe Datei schreiben will, die ich auch auslese, und gleichzeitig Lesen und überschreiben läuft nicht.
    also funzt der Code aus post#15 nun oder nicht? ?(
    Ich entschuldige mich, habe mich vertan. Der Code aus Post 15 funktioniert so, wie ich es brauche.

    Mein VB übernimmt komischerweise sehr ungern einen geänderten Code. Die Funktion, wie ich sie vorher hatte, habe ich durch deine ersetzt. Die .exe hatte er wohl aber noch mit dem alten code erstellt, obwohl ich immer "NEU ERSTELLEN" klicke, und die alte .exe lösche.
    Dadurch ist der Fehler dann wieder aufgetreten.

    Post 1 entsprechend editiert.

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