Frage

Ich habe ein Programm, dass der Bedarf Dateien aus einem Verzeichnis so schnell laden, wie sie geschrieben sind. Ich habe der Filesystemwatcher mich über Änderungen in das Verzeichnis zu benachrichtigen. Anstatt das Ereignis zu prüfen, was sich geändert Ich liste nur die Dateien, und starten Sie alle Verarbeitung, die ich gefunden habe.

Um zu verhindern, versuchen, eine Datei zu lesen, die noch geschrieben werden Ich habe Code wie:

try {
    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite,
                    FileShare.None);
    message = new byte[fs.Length];
    int br = fs.Read(message, 0, (int)fi.Length);
}
catch (Exception e) {
    // I'll get it next time around
    return;
}
finally {
    if (fs != null)
        fs.Close();
}

Das Problem ist, dass für einige Dateien, etwa 1: 200, das Programm aller Nullen gelesen. Dateilänge ist richtig, aber der Inhalt erscheinen alle Null-Bytes sein. Wenn ich die Datei letztere überprüfen finde ich es tatsächlich korrekte Daten enthält. Ich dachte, die Art und Weise war ich die Datei öffnen vorzeitigen Zugriff auf die Datei verhindert wird.

Ich teste diese von Dateien in das Verzeichnis mit dem DOS-Befehl Kopieren ‚kopieren InFile_0 * dropdir‘ (ca. 100 Dateien pro Ausführung.) Möglicherweise dieser Befehl macht die Kopie in zwei Schritten: 1) zuteilen Raum und 2) fill Raum und mein Programm gelegentlich springt in der Mitte der beiden.

Alle Ideen, wie dies zu codieren zuverlässig sein?

Update: Ich habe keine Kontrolle über das Schreibprogramm - es könnte alles sein. Sieht aus wie ich Code haben defensiv.

War es hilfreich?

Lösung

Sie sind die Kollision mit einer Race-Bedingung. Es wird nur noch schlimmer von hier (mit Netzwerkdateisystemen usw.), wenn Sie es endgültig fest.

Versuchen Sie das Programm mit Schreiben der Dateien schreiben jede ein „whatever.tmp“ Namen, dann schließen sie es dann umbenennen. Beim Lesen ignoriert TMP-Dateien.

Oder hält eine leere Datei namens „Sentinel“ oder so in dem Verzeichnis. Holen Sie sich das Programm zu schreiben, die Dateien, die Sentinel-Datei nach jedem erfolgreichen Schreiben einer anderen Datei neu zu schreiben. Dann versuchen Sie nicht, Dateien zu lesen, dessen Änderungsdatum / Zeiten sind> = die Änderung Datum / Uhrzeit der Sentinel-Datei.

Oder, wenn Sie keine Kontrolle über den Autor der Dateien haben, überprüfen Sie jedes Änderungsdatum der Datei / Zeit gegen die aktuelle Systemdatum / Zeit. Lassen Sie die Dateien altern eine entsprechende Menge (ein paar Sekunden, wenn sie klein sind, länger, wenn sie sind größer), bevor sie zu lesen.

Viel Glück. Dies ist ein notorischer Schmerz im Nacken.

Andere Tipps

Nun, ich stimme nicht mit früheren Post von @Ollie Jones.

Sie haben bereits exklusiven Zugriff auf die Datei festgelegt, so dass kein Race-Bedingung Problem.

Ich denke, man sollte den Schriftsteller Verhalten genauer zu untersuchen. Und versuchen, die Störung auf der Access-Datei reduzieren mit nur lesen, teilt alle Zugänge:

fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

Dies könnte Ihre Lese scheitert jedoch Schreibfehler reduzieren. Um zu entscheiden, wenn sicher zu lesen, können Sie überprüfen auf Datei Zeit oder Dateigröße oder was auch immer. Wenn viele Dateien geschrieben werden anschließend können Sie die erste Datei nach der zweiten Datei erstellt lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top