2017-02-08 1 views
1

ich ein FileStream bin mit der Datei zu sperren, nicht für andere Prozesse beschreibbar zu sein und auch lesen und schreiben, ich bin mit folgenden Methode für sie:liest und überschreibe auf dem gleichen Filestream

public static void ChangeOrAddLine(string newLine, string oldLine = "") 
{ 
    string filePath = "C:\\test.txt"; 
    FileMode fm = FileMode.Create; 
    //FileMode fm = FileMode.OpenOrCreate; 
    using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) 
    using (StreamReader sr = new StreamReader(fs)) 
    using (StreamWriter sw = new StreamWriter(fs)) 
    { 
    List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList(); 
    bool lineFound = false; 
    if (oldLine != "") 
     for (int i = 0; i < lines.Count; i++) 
     if (lines[i] == oldLine) 
     { 
      lines[i] = newLine; 
      lineFound = true; 
      break; 
     } 
    if (!lineFound) 
     lines.Add(newLine); 
    sw.Write(string.Join("\r\n", lines)); 
    } 
} 

Ich möchte es mit dem neuen Inhalt überschreiben, aber ich finde nicht das richtige FileMode, mit FileMode.OpenOrCreate einfach nur den neuen Inhalt an die alte und FileMode.Create löscht den Dateiinhalt zu der Zeit, die FileStream fm wurde initialisiert, so dass die Die Datei ist leer.

Ich muss gerade den alten Inhalt löschen, wenn ich den neuen Inhalt schreibe, ohne die Schreibsperre während der Ausführung der Methode zu verlieren.

+0

Mögliches Duplikat von [So löschen Sie den Inhalt einer Datei] (http://stackoverflow.com/questions/4999988/to-clear-the-contents-of-a-file) – Igor

Antwort

1

OpenOrCreate nur anhängt ...

Weil Sie nach dem Lesen nicht neu positionieren.

Das zeigt auch das Hauptproblem mit Ihrem Ansatz: Der FileStream hat nur eine Position, und der Reader und der Writer verwenden stark Caching.

aber solange man alles ersetzen will und wirklich brauchen, dass Sperrschema:

using (FileStream fs = new FileStream(filePath, 
     FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))  
{  
    using (StreamReader sr = new StreamReader(fs)) 
    { 
     ... // all the reading 
    } 
    fs.Position = 0; 
    using (StreamWriter sw = new StreamWriter(fs)) 
    { 
     sw.Write(string.Join("\r\n", lines)); 
    } 
    fs.SetLength(fs.Position); // untested, something along this line 
} 

und vielleicht haben Sie die sw und sr zu überzeugen, ihren Strom offen zu lassen.

Aber ich muss beachten, dass die FileShare.Read Flagge in diesem Szenario nicht zu viel Sinn macht. Ein Leser könnte verschiedene inkonsistente Daten sehen, einschließlich zerrissener Linien und gebrochener UTF8-Zeichen.

+0

Ist es notwendig zu tun: fs.SetLength (fs.Position); ? Es schreibt auch alles in meine Datei ohne dies zu tun und auch wenn der neue Inhalt länger ist als der alte – Pedro

+1

Die 'SetLength()' ist da, falls der neue Inhalt kürzer ist als der alte (könnte sein). Andernfalls können Sie es fallen lassen. –

Verwandte Themen