feststellen, ob eine Datei vollständig geschrieben wurde
-
Hallo,
ich überwache mit FileSystemWatcher ein Verzeichnis, und immer wenn dort eine neue Datei auftaucht dann soll diese Datei gelesen werden. Das Problem dabei ist, dass das Event bereits ausgelöst wird wenn angefangen wird die Datei zu schreiben. Da die Datei relativ langsam über's Netzwerk reinkommt, kann der Fall auftreten dass ich schneller lese als die Datei geschrieben wird. Im Moment behelfe ich mir mit einer festen 50ms Zeitverzögerung, aber das ist keine gute Lösung.
Frage:
Wie kann man feststellen, ob die Datei vollständig geschrieben wurde?
Die Dateigröße kann in meinem Fall unterschiedlich sein.Gruß
Michael
-
"Vollständig geschrieben" lässt sich kaum sinnvoll definieren. Es könnte doch jederzeit noch ein Prozess was reinschreiben wollen.
Vorschlag: Erzeuge die Datei unter einem temporären oder abgewandelten Namen. Der schreibende Prozess benennt sie in den endgültigen Namen um, wenn er fertig ist.
-
Hallo,
Bashar schrieb:
Vorschlag: Erzeuge die Datei unter einem temporären oder abgewandelten Namen. Der schreibende Prozess benennt sie in den endgültigen Namen um, wenn er fertig ist.
Das geht leider nicht, weil ich an dem schreibenden Programm nichts ändern kann.
Gruß
Michael
-
Tja.
-
Hallo,
Bashar schrieb:
"Vollständig geschrieben" lässt sich kaum sinnvoll definieren. Es könnte doch jederzeit noch ein Prozess was reinschreiben wollen.
Das trifft in diesem Fall nicht zu. Jede Datei wird nur einmal geschrieben und dann nie mehr verändert. Der Dateiname enthält eine Nummer die laufend hochgezählt wird.
Gruß
Michael
-
Hilft dir vielleicht der FileSystemWatcher?
-
Vielleicht kann man irgendwie abfragen, ob der Prozess die Datei noch geöffnet hat. Irgendwelche Workarounds wie Überwachen der Dateigröße und seit der letzten Änderung noch ein paar Millisekunden warten schlagen halt bei hoher Systemauslastung oder Netzwerkhängern fehl, das will man nicht wirklich.
-
Evtl. versuchen die Datei mit Schreibrechten zu öffnen (am besten einen Timer dafür benutzen, der solange versucht die Datei zu öffnen, bis es klappt).
-
Th69 schrieb:
Evtl. versuchen die Datei mit Schreibrechten zu öffnen (am besten einen Timer dafür benutzen, der solange versucht die Datei zu öffnen, bis es klappt).
Das ist eine gute Idee, werde ich nachher mal ausprobieren.
Gruß
Michael
-
micha7 schrieb:
Der Dateiname enthält eine Nummer die laufend hochgezählt wird.
Werden die Dateien streng sequentiell geschrieben und entsprechend durchnummeriert? Weil wenn dir der FileSystemWatcher sagt, dass z.B. "File001.txt" aufgetaucht ist, dann schau einfach, ob "File002.txt" schon da ist. Wenn ja, dann kannst du 001 lesen, sonst wartest du.
-
Hallo,
GPC schrieb:
micha7 schrieb:
Der Dateiname enthält eine Nummer die laufend hochgezählt wird.
Werden die Dateien streng sequentiell geschrieben und entsprechend durchnummeriert?
ja.
GPC schrieb:
Weil wenn dir der FileSystemWatcher sagt, dass z.B. "File001.txt" aufgetaucht ist, dann schau einfach, ob "File002.txt" schon da ist. Wenn ja, dann kannst du 001 lesen, sonst wartest du.
Nein, so geht das nicht. Dann würde mir ja immer die letzte Datei in der Auswertung fehlen. Die Dateien kommen nicht in einem festen Zeitraster. Wenn eine Datei kommt, dann muss sie auch gleich gelesen werden.
Gruß
Michael
-
micha7 schrieb:
GPC schrieb:
Weil wenn dir der FileSystemWatcher sagt, dass z.B. "File001.txt" aufgetaucht ist, dann schau einfach, ob "File002.txt" schon da ist. Wenn ja, dann kannst du 001 lesen, sonst wartest du.
Nein, so geht das nicht. Dann würde mir ja immer die letzte Datei in der Auswertung fehlen. Die Dateien kommen nicht in einem festen Zeitraster. Wenn eine Datei kommt, dann muss sie auch gleich gelesen werden.
Das stimmt, das hatte ich nicht bedacht. Dann schließe ich mich Bashar an.. schau nach, welche Prozesse noch Zugriff auf die Datei haben, wenn du lesen willst. Das ist eine recht gute Lösung.
-
Th69 schrieb:
Evtl. versuchen die Datei mit Schreibrechten zu öffnen (am besten einen Timer dafür benutzen, der solange versucht die Datei zu öffnen, bis es klappt).
Die Lösung finde ich hier noch am besten...
private static bool CanWriteFile(string fileName) { try { using (FileStream fs = new FileStream(fileName, FileMode.Open)) { return fs.CanWrite; } } catch { return false; } }
So mache ich das bisher. Ist die Datei nicht schreibbar, dann wird sie später wieder versucht...
Gruß
Hellsgore
-
Hellsgore schrieb:
private static bool CanWriteFile(string fileName) { try { using (FileStream fs = new FileStream(fileName, FileMode.Open)) { return fs.CanWrite; } } catch { return false; } }
Vielen Dank für eure guten Tipps. Bin jetzt erst dazu gekommen die oben angegebene Lösung auszuprobieren. Funktioniert ohne Probleme.
Gruß
Michael
-
"Mit Schreibrechten öffnen" ist Quatsch - was wenn der schreibende Prozess das nicht verbietet?
-> Verwende Leserechte + "share deny write"
-
Kannst du eingrenzen, wie lange der schreibende Prozess braucht um das nächste byte reinzuschreiben?
Wenn ja, könntest du das File einlesen, entsprechend lange warten und dann noch mal einlesen.
Wenn sich was geändert hat, ist der schreibende Prozess noch am schreiben, sonst nicht.Wenn diese Files eine ganz bestimmte Struktur und Länge haben oder eine Prüfsumme, könntest du natürlich auch über diese gehen.
Grüsse
Chiller
-
hustbaer schrieb:
"Mit Schreibrechten öffnen" ist Quatsch - was wenn der schreibende Prozess das nicht verbietet?
-> Verwende Leserechte + "share deny write"
Naja, Quatsch ist was anderes. Das kann man ja recht schnell ausprobieren und eingrenzen. Ist mir persönlich jetzt tatsächlich noch nicht vorgekommen, dass der zu schreibende Prozess die Datei nicht sperrt. Will aber auch nicht damit behaupten, dass das nicht vorkommen kann. Ich denke aber mal das sollte eher die Ausnahme sein.
-
Hallo,
Chiller schrieb:
Kannst du eingrenzen, wie lange der schreibende Prozess braucht um das nächste byte reinzuschreiben?
Nein. Woher soll ich wissen wie schnell oder langsam das Netzwerk ist?
Die Lösung, die Hellsgore oben angegeben hat, funktioniert. Daher sehe ich im Moment keinen Grund daran noch irgendwas zu ändern.
Gruß
Michael