2016-06-07 5 views
2

In meiner Testumgebung habe ich zwei physische Windows 7-Clients. Beide haben Zugriff auf eine Netzwerkfreigabe, die auf einem Windows Server-System gehostet wird.Unsicher über den Mechanismus zum Sperren von Dateien in C# .NET

Die Clients führen jeweils eine Anwendung aus, die versuchen kann, dieselbe Textdatei gleichzeitig zu lesen oder zu schreiben.

Ich mag die FileInfo.Open() Methode verwenden, um verschiedene Szenarien zu realisieren:

Szenario 1: Die Anwendung ermöglicht es zugleich zu lesen. Es sollte fehlschlagen, wenn eine andere Instanz tatsächlich darauf schreibt.

würde ich

FileInfo fi = new FileInfo(filePath); 
using (FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    // Do some read operations... 
    Console.WriteLine("Press ENTER to close file-stream..."); 
    Console.ReadLine(); 
} 

dafür.

Szenario 2: Nur eine Instanz darf eine Datei öffnen, wenn sie versucht, darauf zu schreiben. Und es sollte fehlschlagen, wenn eine andere Instanz es tatsächlich liest.

würde ich

FileInfo fi = new FileInfo(filePath); 
using (FileStream fs = fi.Open(FileMode.Open, FileAccess.Write, FileShare.None)) 
{ 
    // Do some write operations... 
    Console.WriteLine("Press ENTER to close file-stream..."); 
    Console.ReadLine(); 
} 

dafür.


Mit den Code-Schnipsel oben funktionieren meine Szenarien wie erwartet. Obwohl ich eine Instanz innerhalb der using(...) Anweisung geschlossen habe, wird die Datei "entsperrt".

Q1: Ich denke darüber nach, ob bei einem Programmabsturz irgendetwas passieren könnte, so dass andere Instanzen Zugriff auf die Datei verweigert werden (für ein paar Zeit?).

Q2: Was passiert, wenn eine Netzwerkverbindung unterbrochen wird, während eine Datei geöffnet wird?

Q3: Gibt es Gründe (zusätzlich) verwenden, um die FileStream.Lock() und Unlock() Methoden explizit Sperre und eine Datei entsperren?

Q4: Benötigt das System des Servers irgendetwas, damit die Dateisperrung ausgeführt wird?

Q5: Gibt es zusätzliche Punkte, über die ich nachdenken muss?

+1

Überlegen Sie, was passiert, wenn jemand versucht, die Datei mit einem Programm zu öffnen/zu ändern, das nicht in Ihrer Kontrolle ist. Sie werden nicht immer die Lock-Typen verwenden, die Sie erwarten. – CathalMF

+0

@CathalMF Guter Punkt. Aber ich denke, in meinem Fall liegt es an den Endnutzern, dies nicht zu tun. Die Leute werden (hoffentlich) wissen, was sie tun :-) –

+0

Wir alle hoffen, dass unsere Benutzer wissen, was sie tun. Aber es gibt immer diese eine Person !! Stellen Sie nur sicher, dass Ihre App nicht explodiert, wenn jemand die Datei mit einer Kombination aus Freigabeberechtigungen und Lesen/Schreiben öffnet. – CathalMF

Antwort

3

... könnte alles auf einem Absturz der Anwendung passieren

Nicht besonders, wird die Sperre sofort freigegeben, wenn das Betriebssystem die Schrapnell bereinigt und schließt alle Dateien, die von der App nicht geschlossen wurden.

Was passiert, wenn eine Netzwerkverbindung unterbrochen wird, während eine Datei geöffnet wird?

Sie erhalten eine Laufzeitausnahme, IOException. Nur wiederherstellbar durch Wiederherstellen der Netzwerkverbindung und erneutes Öffnen der Datei. Netzwerke sind im Allgemeinen zuverlässig genug, um dies nicht automatisch zu tun, YMMV.

Gibt es Gründe (zusätzlich) verwenden, um die FileStream.Lock() ...

Nein, diese Funktion Sperrdatei Daten statt Dateizugriff. So etwas würde eine Datenbank-Engine machen. Es gilt nie für eine Textdatei, da es sich um Streams handelt und Sie nie die genaue Dateiposition einer Textzeile in der Datei kennen.

Hat der Server System alles benötigt ...

Nein, diese in das Betriebssystem integriert sind.

Gibt es zusätzliche Punkte, über die ich nachdenken muss?

Sie sollten wahrscheinlich mehr über das Schreiben der Datei denken, jemand wird es tun müssen. Die Verwendung von FileShare.None ist einfach, tendiert jedoch dazu, bei Textdateien etwas grob zu sein, insbesondere wenn es sich um Protokolldateien handelt, die immer offen gehalten werden. Es ist technisch möglich, dass eine App eine Datei liest, die gerade geschrieben wird. Tendiert dazu, gut auszusehen, da Textdateien nur immer angehängt werden. Sie würden FileShare verwenden. Lesen Sie die App, die die Datei schreibt, und FileShare.ReadWrite in die App, die die Datei liest. Kein Tippfehler.

+0

Vielen Dank für die tolle Antwort. Können Sie mir erklären oder einen Link teilen, warum System B weiß, dass System A tatsächlich eine Datei auf einer Netzwerkfreigabe verarbeitet? –

+1

System B weiß nicht, es fragt, welches System die Datei besitzt. Job des Netzwerk-Redirectors. Ich kenne keine Links. –

+0

Zusätzlich, was in meiner vorherigen Frage beantwortet werden kann, wie erkennt die Datei, dass es nicht mehr gesperrt ist, wenn das Schließsystem sofort abstürzt (herunterfahren)? –

2

Die Dateisperre, auf die Sie sich beziehen, erfolgt auf Betriebssystemebene. Wenn also die Anwendung abstürzt, Fehler auftreten usw., wird die Datei freigegeben. Dies gilt für Q1 und Q2 (obwohl Q2 von der Netzwerktopologie und dem Sicherungsspeicher abhängt). Das Sperren einer Datei kann zu merkwürdigen Leistungsproblemen bei einem Sicherungsspeicher führen, für den die Pufferung aktiviert ist. Q3, das Lock, Unlock verweist darauf gibt es keine Dateisperre, sondern Bytes innerhalb einer Datei. Das ist ein völlig anderes Konzept und es wird Sie seltsam Verhalten auf NAS-Speicher Q4 verursachen, wie ich schon sagte, bevor es ein Betriebssystem-Level-Konzept ist. Q5. Denken Sie an einen besseren Weg, dies zu verwalten, eine Datei zu verwenden ist ein relativ altes Konzept, aber die gemeinsame Nutzung einer Datei zwischen mehreren Computern in einem Netzwerk, IMHO, fragt nach seltsamen Kopf kratzen Verhalten.Der moderne Dateispeicher ist nicht auf dieses Konzept ausgerichtet und mit Pufferung, Latenz und Sicherheit wird es zur Herausforderung. Vermeiden Sie es, wo Sie können. Sollte dies nicht der Fall sein, stellen Sie sicher, dass Sie Ihre Anwendung so optimieren, dass sie die Datei öffnet, schreibt, schließt und den Stream so schnell wie möglich löscht.