Autor Beitrag
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 11.01.14 21:06 
Moin,

ich möchte eine Datei in einen MemoryStream lesen, dort bearbeiten und anschließend wieder in die zuvor geöffnete Datei schreiben.

Das hat den Sinn, dass ich dann einige Dateien bearbeiten kann, ohne, dass die originale Datei geändert wird, bis die Änderungen dann wieder geschrieben werden.
Ich habe dann sozusagen eine Dummy-Datei im Speicher und kann beliebige Änderungen machen, ohne Gefahr zu laufen, das Original zu beschädigen.

Ich hab dafür einen FileStream geöffnet und für andere Prozesse gesperrt, kopiere diese Daten in einen MemoryStream, schreibe dort anschließend eine Zeichenfolge rein und kopiere dessen Inhalt schlussendlich dann wieder in die Datei.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
using (var file = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    using (var fileMemory = new MemoryStream())
    {
        file.CopyTo(fileMemory);

        using (var writer = new StreamWriter(fileMemory))
        {
            writer.Write("4321");

            fileMemory.CopyTo(file);
        }
    }
}


Das Ergebnis ist kein Fehler und kein Unterschied in der Datei.

Ich habe in der Datei 1234 stehen und müsste danach 4321 finden können, ist aber nicht so.

Kann mir jemand einen Hinweis geben, was ich falsch gemacht habe?


Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 11.01.14 22:00 
Du mußt die Position in fileMemory wieder zurücksetzen setzen. Du hast in fileMemory was reingeschrieben also ist die aktuelle Position dahinter und da ist halt nix.
Das fileMemory.CopyTo(file) kopiert also nix da ab der aktuellen Position in fileMemory auch nix ist.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 11.01.14 22:17 
Aber ich kann in mit dem StreamReader auch am Ende Daten anhängen, oder?

Dann müsste ich doch eigentlich zwischen dem Schreiben und dem Kopieren in die Datei beide Streams (file und fileMemory) an den Anfang setzen können, damit dann der gesamte Inhalt vom Memory in die Datei geschrieben wird, oder

Ich habe deshalb testweise die Datei mit SetLength gelöscht (oder gibt es dafür eine bessere Methode?) und den fileMemory an den Anfang gesetzt, bevor ich dann die Datei mit dem Memory neu beschreibe.

Sieht jetzt so aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
using (var file = new FileStream(@"C:\Users\Malte\Documents\visual studio 2012\Projects\IODummy\IODummy\bin\Debug\test.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    using (var fileMemory = new MemoryStream())
    {
        file.CopyTo(fileMemory);

        using (var writer = new StreamWriter(fileMemory))
        {
            writer.Write("4321");

            file.SetLength(0);
            fileMemory.Position = 0;

            fileMemory.CopyTo(file);
        }
    }
}


Immer noch das gleiche Ergebnis, nämlich gar keins.

Ich hab auch mal den absoluten Pfad zur Datei ausprobiert, nicht, dass ich die ganze Zeit an einer falschen Stelle schreibe.
Auch das Setzen der Position vom Memory vor dem Schreiben hat keinen Unterschied gemacht.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 11.01.14 22:29 
Zwischen schreiben in den MemoryStream und lesen aus dem Memorystream solltest du den writer noch flushen sonst ist das im Memorystream noch nicht angekommen.
Und nein ein StreamReader kann nicht schreiben ;)

Wenn du tatsächlich anhängen will verstehe ich nicht was das ganze soll. Ich dachte du wolltest irgendwo mitten im File was ändern und das hier wär nur ein Beispiel.
Wenn du anhängen willst würde ich einfach auch nur eine der File.Append~Irgendwas~ Überladungen benutzen.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 11.01.14 23:42 
Es geht darum, dass ich nicht nur in der Mitte etwas ändern will, sondern allgemein.

Also ein Stream, in dem beliebig geändert werden kann, bis es dann tatsächlich im eigentlichen Ziel-Stream ankommt.

Und wenn ich den Writer zwischendurch flushe, funktioniert es jetzt, danke :D



Wo ich jetzt gerade schon dabei bin, eine kleine Frage zum FileStream:

Wenn ich den öffne, aber nichts daran ändere, wie sieht dann die Belastung vom RAM aus?
Ich kenne keine andere Möglichkeit, eine Datei zu sperren, als einen FileStream zu öffnen und dabei dann zu sperren.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 12.01.14 01:03 
Zitat:
Wenn ich den öffne, aber nichts daran ändere, wie sieht dann die Belastung vom RAM aus?


Ich gehe schwer davon aus das das die FileStream Klasse sich erstmal nur einen Handle auf das File (was du auch selbst machen könntest über die WinAPI um dann später mit dem Handle einen FileStream zu erzeugen) ranholt und sein Buffer erst beim ersten lesen erzeugt. Und der Buffer ist standardmäßig 4K groß deutlich mehr wird ein Filestream also nie brauchen.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 12.01.14 01:35 
Dann passt das ja ^^

Darf ich nur nicht zu viele Dateien auf einmal sperren, sonst läuft mir der Speicher voll :D