StreamWriter Verständnisfrage

  • VB.NET
  • .NET (FX) 4.0

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von razzzer530i.

    StreamWriter Verständnisfrage

    Moin Leute,
    generelle Frage zum StreamWriter.
    Wenn ich eine extrem große Datei habe die ich schnell bearbeiten möchte, dann ist der SW ja klasse. Zumindest wenn es mehrere Lines gibt. Jetzt habe ich eine Datei die ca. 100MB groß ist und aus einer Line besteht. Sie besteht aus einem String, an dem für jede neue Nachricht ein String mit einer Länge von 430 byte angehangen wird, der alle Infos über Speicherort usw. enthält.

    Darin möchte ich bestimmte Zeichen an bestimmten Stellen bearbeiten, ohne den gesamten Inhalt neuzuschreiben.
    Bringt mich der SW da weiter?
    wie genau stelle ich das richtig an? Zur Zeit lese ich den Inhalt mit ReadAllText ein und schreibe die Datei mit WriteAllText komplett neu.
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Wenn die Positionen der Einträge, welche du ändern willst, IMMER fest/bekannt sind (sich also algorithmisch ermitteln lassen), dann kannst du versuchen mit der Klasse FileStream aus dem Namespace System.IO zu arbeiten.

    Diese Klasse leitet von Stream ab und bietet dir die Möglichkeit die Position des Stream (also die Position des Zeichens, mit dem du arbeiten willst) festzulegen. Außerdem erlaubt dir die Klasse über die Methoden Read() und Write() mit Hilfe der aktuellen Position und einem Offset, Positionsgenau Daten zu lesen und zu schreiben. Einziger Nachteil: Das Schreiben und Lesen erfolgt über byte-Arrays.
    Das bedeutet konkret: Wenn du einen Teil aus der Datei lesen willst, dann musst du mit Read() arbeiten, das Ergebnis aus dem ersten Parameter - dem buffer über die Klasse Encoding aus dem Namespace System.Text über die Property UTF8 mit der Methode GetString() wieder in einen (für Menschen) lesbaren String konvertieren.

    Willst du hingegen einen Text schreiben, musst du den umgekehrten Weg gehen und den Text (als String) der Funktion GetBytes() an die Property UTF8 der Klasse Encoding weiterreichen, das Ergebnis in einem Byte-Array speichern und per FileStream.Write(buffer, offset, length) in die Datei schreiben.

    Ich hoffe ich kann dir helfen
    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator

    Also es ist so:

    Ich lease den Text ein mit ReadAllText(geht sehr schnell)
    Darin kann ich ohne Probleme den Index herausfinden, an dem mein zu tauschender String beginnt.
    Also ich habe

    eine Textdatei X
    einen String(ReadAllText(X))
    den Index vom Anfang des Strings den ich taschen will aus der Textdatei
    Jetzt möchte ich die TxtDatei öffnen, am index(I) ansetzen,die folgenden Zeichen bis zu Index(I2) entfernen und dafür meinen neuen String einsetzen.
    und das schnell Ohne ein komplettes überschreiben...

    Weiß nicht ob ich dir da so genau folgen kann. übergebe das aktuell auch noch mit encoding.default, da ich die Zeichen nicht verändern darf, die mir das System in die Textdatei schreibt.
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Moin!

    Du kannst auch einfach einen FileStream aufmachen und damit deinen StreamWriter instanziieren. Wenn du im FileStream Position änderst, schreibt der StreamWriter automatisch dahin. Natürlich nur bei nachfolgenden Schreibvorgängen.

    C#-Quellcode

    1. using (var fs = File.Open("TolleDatei.txt", FileMode.Open))
    2. {
    3. using (var writer = new StreamWriter(fs))
    4. {
    5. fs.Position = 42;
    6. writer.Write("Hello World!");
    7. // Wichtig! Hier wird tatsächlich erst geschrieben.
    8. // Wenn AutoFlush nicht True ist, werden die zu
    9. // schreibenen Daten erst gepuffert, um in größeren
    10. // Blöcken zu schreiben.
    11. writer.Flush();
    12. fs.Position = 30;
    13. writer.Write("Data");
    14. }
    15. }
    Mit freundlichen Grüßen,
    Thunderbolt
    Hilft mir schon aber ich verstehe noch nicht so ganz wie folgendes geht:

    ....asdfjk wd i qwie 2131i asid i qi324 \\pfad\x\datei asd kwdm . ado . . ..... usw. Da steht irgendein Rotz drin und die Datei ist 10 MB groß(nur eine line)
    Den index von \\ habe ich bereits. Jetzt möchte ich an genau dieser stelle ansetzen unde den 2. char tauschen. z.B.
    Wie genau funktioniert das mit dem Positionieren? Also wie muss ich das genau verstehen.
    Sorry dass ich da auf dem Schlauch stehe. Ist sicher ganz easy die Kiste
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    @Thunderbolt
    Den Umweg über einen FileStream halte ich für unnötig, der StreamWriter stellt den BaseStream selbst zu verfügung.

    C#-Quellcode

    1. using (System.IO.StreamWriter sw = new System.IO.StreamWriter("...")) {
    2. sw.BaseStream.Position = 42;
    3. //...
    4. }

    C#-Quellcode

    1. using (System.IO.StreamWriter sw = new System.IO.StreamWriter("...")) {
    2. sw.BaseStream.Position = 42;
    3. //...
    4. }


    Also mir ist klar, dass ich in meiner Datei an pos. 42 anfange zu schreiben. Aber habe ich da dann überhuapt die möglichkeit das Zeichen an Position 43 zu löschen? Bzw direkt das Zeichen an Pos. 42?
    Kann ja nicht StreamWriter.Write(lösche zeichen) machen. Oder verstehe ich das komplett falsch?
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Also bei dem String "Hallo World!" würde ich mit

    VB.NET-Quellcode

    1. ​sw.BaseStream.Position = 6
    2. sw.Write("Test")


    den String in "Hallo Testd!" ändern?

    Code-Tags eingefügt. ~Thunderbolt
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~

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

    Danke :) Läuft jetzt wie ich das wollte.

    Vollzitat entfernt. ~Thunderbolt
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~

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