2016-06-19 19 views
1

Wie der Titel schon sagt, versuche ich gleichzeitig in eine Datei zu lesen und zu schreiben. Ich habe dieses Thema recherchiert, aber die Antworten, die ich gefunden habe, scheinen wegen der Umstände in meinem Programm nicht für mich zu funktionieren. Ich verwende mehrere FileSystemWatchers, um eine große Anzahl von Dateien zu verfolgen, die ständig einen Fluss in meinem Netzwerk durchlaufen. Während die Dateien durch jeden Teil meines Flow laufen, wird eine Textdatei aktualisiert (eine Textdatei pro Stelle im Fluss), die den Namen der Datei und die Zeit angibt, in der sie im Ordner erstellt wurde. Es ist unberechenbar, wenn Dateien durchgehen und wenn sie in die Tracker-Textdateien schreiben. Mein Ziel ist es, in der Lage zu sein, gleichzeitig in die Datei zu lesen und zu schreiben, falls ein Benutzer versucht, aus einer Textdatei zu lesen, in die zur gleichen Zeit geschrieben wird. Wie würde ich das erreichen?Verwenden von TextWriter mit StreamWriter und gleichzeitiges Lesen/Schreiben

//Write to File 
    private void WriteToFile(string info,string path,string tr) 
    { 
     if (!File.Exists([email protected]"\"[email protected])) 
     { 
      var myFile = 
      File.Create(path + @"\" + @tr); 
      myFile.Close(); 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info,true); 
      tw.Close(); 
     } 
     else if (File.Exists(path + @"\" + @tr)) 
     { 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info); 
      tw.Close(); 
     } 
    } 
+0

Können Sie bitte den Code, der für das Lesen der Datei verantwortlich ist, zu Ihrer Frage hinzufügen? Vielen Dank! – Snoopy

+0

Wenn Sie FileStream verwenden, können Sie einen Teil der Datei https://msdn.microsoft.com/en-us/library/system.io.filestream.lock sperren oder die Option FileShare.None verwenden – Slai

Antwort

1

Die Umstände Sie zu sagen anspielen scheinen, dass, während mehrere Versuche unternommen werden können, um die Datei zu einem bestimmten Zeitpunkt zu lesen/schreiben, Sie wollen immer noch dafür sorgen, dass die Vorgänge in einer nach dem anderen ausgeführt werden die richtige Reihenfolge, in der das Lesen oder Schreiben aufgerufen wurde.

Eine einfache Methode, um sicherzustellen, dass die lesen und schreiben Operationen nur eine lock oder Monitor um die Methoden zu setzen wäre synchronisiert zu. Versuchen Sie, den folgenden Code für Ihre Schreib Methode:

private readonly object _locker = new object(); 

// write the file 
private void WriteToFile(string info, string path, string tr) 
{ 
    Monitor.Enter(this._locker); 

    try 
    { 
     if (!File.Exists(path + @"\" + @tr)) 
     { 
      var myFile = 
      File.Create(path + @"\" + @tr); 
      myFile.Close(); 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info, true); 
      tw.Close(); 
     } 
     else if (File.Exists(path + @"\" + @tr)) 
     { 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info); 
      tw.Close(); 
     } 
    } 
    finally 
    { 
     Monitor.Exit(this._locker); 
    } 
} 

Dann würde ich ein sehr ähnliches Konstrukt für verwenden die Datei zu lesen.

// read the file 
private string ReadFile(string path) 
{ 
    Monitor.Enter(this._locker); 

    try 
    { 
     // read the file here... 
    } 
    finally 
    { 
     Monitor.Exit(this._locker); 
    } 
} 

Was die Monitor tun werden, ist sicherzustellen, dass die Datei read erst eine laufende write Operation abgeschlossen sein wird (und umgekehrt). Dadurch wird sichergestellt, dass Sie die alten Daten nicht erhalten, wenn Sie sie lesen, und Sie werden auch die neuen Daten (die noch nicht gelesen wurden) nicht überschreiben. Diese Methode überprüft die Integrität Ihrer Dateien zu jeder Zeit.

+0

Wie genau funktioniert das? Wenn ich es verstehe, "sperrt" die Datei, bis es möglich ist zu lesen/schreiben? Und würde ich im Leser immer noch einen einfachen Filestream-Reader verwenden? –

+0

@MarshalAlessi Es wird eigentlich nur eine Sperre auf das Objekt setzen. Daher kann die Methode 'ReadFile' nicht ausgeführt werden, während' WriteFile' ausgeführt wird. Sie blockieren * tatsächlich * auf dem '_locker'-Objekt. Mit anderen Worten, zu einem bestimmten Zeitpunkt kann sich nur ein Thread über den "Monitor" bewegen, bis der Thread, der beschäftigt ist, den Monitor.Exit() erreicht und bereit ist, die Sperre aufzugeben. Ist das sinnvoll? – Snoopy

+0

Vielen Dank für Ihre Erklärung und Antwort! Ich habe noch eine weitere Frage, ich habe gerade diese Methode getestet und es erzeugt nun seltsamerweise vier Datenzeilen pro neuer Datei. IE, wenn es in die Textdatei schreibt, dupliziert es die gleiche Zeile 4 mal. Was könnte das verursachen? –