Java: Ordner auf Aenderungen ueberwachen

Greenleon

Greenleon

Tripel-As
Taag,

Ein Java-Programm ueberwacht einen Ordner auf Aenderungen, indem der entsprechende Thread sich alle paar Sekunden den Ordnerinhalt auflisteten laesst.
Alle neuen Dateien werden dann zur weiteren Verarbeitung geladen.

Das Problem dabei ist folgendes: Wenn sich eine Datei noch im Kopiervorgang befindet, ist sie in der Liste enthalten. Wenn ich sie dann aber ins Programm lade habe ich eine unvollstaendige Datei und unvorhersehbares Verhalten tritt auf.

Gibt es irgendwelche eleganten Methoden, das zu verhindern?

Die einzige Loesung, die mir einfaellt, ist, die Dateien immer auf ihre Groesse zu ueberpruefen und sie dann erst zu laden, wenn zwei aufeinanderfolgende Pruefdurchlaeufe die gleiche Groesse fuer eine Datei ermitteln.
 
Kann man eventuell die Prozessliste (ps aux) fetchen und dort gucken ob mit der Datei gerade was gemacht wird?
»lsof« gibt es auch noch.

Wie man das allerdings in Java Aufrufen kann (vorhandene Klassen?) weiß ich allerdings nicht.
 
Vllt hast gibts ja eine java bibliothek, die mit inotify kann. Alternativ kannst du das java programm erst mit incron starten.
 
Wie wäre es, wenn du die Dateien beim reinkopieren erst mal datei.part nennst, so wie z.B. der Firefox das tut. Wenn die Kopie dann beendet ist einfach umbennen und im Programm .part ignorieren. Das mit der Größe wäre evtl. auch ein Ansatz ist aber m.E. nicht so sauber.. Erzähl mal bitte ein bisschen mehr über den Hintergrund..
 
saeckereier: nicht so gut... das Programm ist nicht fuer mich... sollte moeglichst einfach sein.
Das Programm laedt Dateien verschiedener Formate und zeigt sie als "Diashow" an. Bei mehrseitigen UTF-8/ASCII Dateien scrollt der Text. Wird nacher fuer einen Info-Monitor genutzt. Bislang lassen sich die Dateien aber nur "per Hand" laden, d.h. man gibt den Pfad zu einer Datei, einem Ordner voller Dateien an und die werden geladen. Beim naechsten Schritt, stosse ich eben auf das im Anfangspost genannte Problem.

sim4000: dann ist es nicht mehr plattformunabhaengig.. leider auch nicht so gut

marcellus: gute Idee. Hab das hier gefunden http://jnotify.sourceforge.net/. Schau ich mir mal genauer an

HPollak: Wenn das funktionieren sollte, waer das sogar die beste Loesung, da es ohne nativen Code auskommt. Das probier ich als erstes mal. Ich hab nur die Befuerchtung, dass der Wert einfach angibt, wann der Schreibprozess begonnen hat. Bei grossen Dateien hilft das dann gar nicht.
 
Zuletzt bearbeitet:
Inotify sollte eher nicht helfen. Schliesslich gibt es kein Event "Kopieren beendet" Wie sollte es auch. Wäre aber interessant um nicht immer das komplette Verzeichnis zu pollen. Ist eben die Frage wie viele Dateien da rein kommen sollen..
 
Hm, mist. Ich schaetze auf 30 Dateien im Extremfall...
Dann werd ich wohl doch immer das ganze Verzeichnis ueberpruefen, bevor ich mir noch mehr nativen Code ans Bein haenge.

Weiss jemand, wie sich der lastModified Wert unter Windows verhaelt? Wann wird der gesetzt? Wie ist es unter linux?
 
Ist vielleicht eine dumme Frage, aber wie verhält sich eine zum schreiben geöffnete datei, wenn du sie zum schreiben öffnen willst?

Wegen inotify würds ja auch reichen, dass du bei einer neuen datei zyklisch das modified signal abfängst und wartest, bis es nicht mehr kommt.
 
Ist vielleicht eine dumme Frage, aber wie verhält sich eine zum schreiben geöffnete datei, wenn du sie zum schreiben öffnen willst?

Ist glaub ich Plattformabhaengig.

Fuer inotify muesste ich halt diese jnotify lib nehmen. Ist unschoen, da das zum groessten Teil nativer Code ist.
 
Und sinnfrei. Bei 30 Dateien und anscheinend eh nur verzögerter Anzeige ist das viel zu komplex. Zu mindest meiner Meinung nach. Klar, zum lernen wäre es was nettes. Aber bei Java plattformabhängigkeit zu erzeugen ist erfahrungsgemäß immer doof.
 
Vorschlag

Das Problem dabei ist folgendes: Wenn sich eine Datei noch im Kopiervorgang befindet, ist sie in der Liste enthalten. Wenn ich sie dann aber ins Programm lade habe ich eine unvollstaendige Datei und unvorhersehbares Verhalten tritt auf.

Wie wäre es wenn du vom Original einen Hash bildest wie z.B. MD5 und dann wenn du die Datei lädst, den Hash von der kopierten Datei vergleichst. Erst wenn der Hash beider Dateien identisch ist, kannst du davon ausgehen, dass der Kopiervorgang abgeschlossen ist. Sollte dieser einfache Ansatz nicht dein Problem lösen?
 
Zuletzt bearbeitet von einem Moderator:
Wann soll ich den Hash generieren? Ich kann ja erst hashen, wenn die Datei schon geladen ist...
 
Die Idee war, während die Datei halb da ist einen Hash zu berechnen und danach wieder. Wenn er sich verändert, wird die Datei noch kopiert. Keine Ahnung was man rauchen muss, um auf sowas zu kommen :-) Das wäre so ziemlich die unsinnigste Verwendung eines Hashes die mir einfällt.. Von allen vorgeschlagenen Lösungen scheinen bisher wirklich Änderungsdatum und Größe als die praktikabelsten.
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Alternativ lies dir mal das hier durch, lade das Beispiel runter und guck mal, wann das Event für file creation ausgelöst wird:

http://java.sun.com/docs/books/tutorial/essential/io/notification.html
 
Zuletzt bearbeitet:
@sackeier
nein, das ist nicht der ansatz - da hast du was geraucht

Vorausetzung: man kennt den Hash der Original Datei
Vor dem Laden erfolgt die Prüfung der Datei - stimmt der Hash nicht überein wird die Datei nicht geladen

das ist der ansatz - simpler vergleich -

apache projekte liefern zu ihren downloads immer auch einen md5-datei mit, damit man den Download verifizieren kann

@TE
der Lösungsansatz ist, bevor die Dateien in den Ordner wandern den Hash zu kennen
 
Wo steht, das vorher bekannt ist, welche Dateien kopiert werden? ;)
 
@sackeier
nein, das ist nicht der ansatz - da hast du was geraucht

Vorausetzung: man kennt den Hash der Original Datei
Vor dem Laden erfolgt die Prüfung der Datei - stimmt der Hash nicht überein wird die Datei nicht geladen

das ist der ansatz - simpler vergleich -

apache projekte liefern zu ihren downloads immer auch einen md5-datei mit, damit man den Download verifizieren kann

@TE
der Lösungsansatz ist, bevor die Dateien in den Ordner wandern den Hash zu kennen

Ahh, sorry, ja das würde eventuell Sinn machen. Aber auch hier muss man dazu sagen, das ich den Hash trotzdem erst nach dem Kopieren berechnen würde. SHA-1 (und mindestens den sollte man nehmen und nicht MD5) kostet auch Ressourcen und das würde dann ausgesprochen schlecht skalieren.. Sorry, dass ich dich missverstanden habe. Aber die Dateien sollen ja einfach nur in einen Ordner geschmissen werden können, daher kennt man weder die Dateien noch die Hashes von vorneherein. Du hättest evtl. deinen Ansatz etwas deutlicher erklären können..

EDIT: Hast du deinen Post noch geändert, das das deutlicher wird? Falls nicht, dann nehm ich das zurück, dann hatte ich mich einfach verlesen.
 
Wo steht, das vorher bekannt ist, welche Dateien kopiert werden? ;)

Nirgends, aber ein Problem kann man auch lösen, wenn es von verschiedenen Perspektiven betrachtet wird, bzw. kommt man vielleicht auf einen anderen Lösungsweg :think:

Ahh, sorry, ja das würde eventuell Sinn machen.

Kein Problem. Missverständnisse gibt es halt. Ja ich hätte meinen Ansatz auch besser beschreiben können.

Dein Artikel ist ja auch ein guter Ansatz, funktioniert halt nach dem Observer-Pattern. Ein ähnlicher Artikel gibt es hier.

Abgesehen ist auch abgedreht nicht ganz verkehrt. Wenn man manchmal verrückte Ideen bzw. Lösungsansätze hat. Genie und Wahnsinn sag ich nur. Aber bin Nichtraucher. Und so schlecht finde ich die Idee gar nicht.
 
Zuletzt bearbeitet von einem Moderator:
Ja ich kenn den Hash aber nicht ... das sind zum Grossteil PDFs.
Ich hab das jetzt mit Aenderungsdatum realisiert. Dateien die juenger als 5sec werden uebergangen. 1 Zeile Code. Bisher lief das fehlerfrei. Windows machte zwar erst Probleme, da scheinbar ein bereits geschlossenes RandomAccessFile noch gelockt ist in W2k aber nachdem ich auf streamendes Laden umgestellt hatte ging auch das Loeschen. Denke das funktioniert soweit jetzt alles.
Nachdem alle Dateien im Cache einmal komplett angezeigt wurden ueberprueft der den Ordner und holt sich neue/geaenderte Dateien. Falls mal eine Datei unvollstaendig geladen wurde, was eigentlich nicht passieren kann aber ich weiss nicht, wie fehleranfaellig da WIndows ist, was das Aenderungsdatum betrifft wird die Datei genau 1 mal fehlerhaft angezeigt und beim naechsten Durchlauf (hoffentlich) neu geladen.
 
Zuletzt bearbeitet:
Wenn du versuchst ein Lock auf die Datei zu setzen solltest das nur funktionieren wenn sie nicht bereits von einem Prozess geöffnet ist. Wenn du auf die Datei ein Lock setzen kannst muss sie somit _eigentlich_ fertig heruntergeladen sein.
Natürlich wäre es dann auch noch schön den CRC oder MD5 Hash der original Datei zu kennen um ihn mit dem der heruntergeladenen abzugleichen.

(Hashing von Dateien ist gängige Praxis um korrektes herunterladen zu prüfen, da Sicherheit auch irrelevant ist ist auch MD5 sowie CRC32 kein Problem und auch der Performance Impact ist relativ vernachlässigbar. In diesem Fall ja aber wie schon erwähnt nicht anwendbar)
 

Ähnliche Themen

ordner auf änderungen überwachen

Zurück
Oben