[Java] SyncTool - Dateiüberwachung

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Blackb!rd, 10. Juni 2013 .

Schlagworte:
  1. 10. Juni 2013
    SyncTool - Dateiüberwachung

    Hallo Zusammen,

    ich versuche gerade ein kleines Tool zu bauen um Dateien zu Synchronisieren. Leider stehe ich vor dem Problem, das WatchEvent mir beim erstellen eines Ordners unter Windows zwei Event's wirft:
    - Neuer Ordner
    - {Name des Ordners}

    Habt ihr ein Tipp für mich wie ich das für mein SyncTool am besten verarbeiten soll?



    Gruß BlackB!rd
     
  2. 10. Juni 2013
    AW: SyncTool - Dateiüberwachung

    Ohne deinen Code zu kennen kann man da nicht viel zu sagen. Entweder das erste Event ignorieren oder vorm Synchronisieren prüfen, ob es einen Ordner "Neuer Ordner" gibt.
     
  3. 10. Juni 2013
    AW: SyncTool - Dateiüberwachung

    Hey,

    der spezielle Code sollte hier keine Rolle spielen. Ich arbeite mit der WatchService-Lib. Bei dieser Lib schlagen drei Events an:
    • StandardWatchEventKinds.ENTRY_CREATE
    • StandardWatchEventKinds.ENTRY_DELETE
    • StandardWatchEventKinds.ENTRY_MODIFY

    Ein Rename zB wird mit DELETE,CREATE wiedergespiegelt.
    Ein Speichern eines Worddokument's mit CREATE(Tmp-File),MODIFY(Tmp-File),CREATE(Eigentliches-File),DELETE(Tmp-File).

    Vielleicht gibt es ja auch eine andere Möglichkeit Dateien zu überwachen, diese ist aber die einzige die ich gefunden habe. Und irgendwie muss es ja machbar sein...


    Gruß Blackb!rd
     
  4. 11. Juni 2013
    Zuletzt bearbeitet: 11. Juni 2013
    AW: SyncTool - Dateiüberwachung

    Was soll "{Name des Ordners}" für ein Eventtyp sein?

    Entweder du lernst dich präzise zu formulieren (z.B. die entsprechende Library direkt im Startpost nennen) oder du postest tatsächlich deinen Code. Dann kann man dir wahrscheinlich innerhalb von 5 Minuten helfen. Keine Sorge, der Code wird nicht von den Chinesen kopiert. Zumindest ein Ausschnitt wäre angebracht.

    Ansonsten prüfe halt ob die beiden Events sich auf den selben Ordner beziehen. Schreib dir eine entsprechende Abfrage für die Ausnahme. Oder verändere die Library für deine Zwecke, wenn das Verhalten nirgendwo gewünscht ist.


    //
    WatchEvent (Java Platform SE 7 ))

    Ich würde mir einen Algorithmus schreiben der erst mal generell alle Events für einen Kontext zusammenfasst und dann schaut was übrig bleibt. Wenn eine Datei zwischen den Synchronisierungen z.B. erst umbenannt und dann gelöscht wird, ist das Umbenennen-Event hinfällig. Genauso würde dabei dann dein Doppelungsproblem wegfallen.
     
    1 Person gefällt das.
  5. 11. Juni 2013
    AW: SyncTool - Dateiüberwachung

    Ja sorry ich habe mich etwas ungünstig ausgedrückt. In meinem zweiten Post habe ich ja weitere Informationen geliefert. Ein CodeAuschnitt war meiner meine zwar nicht sinnvoll, weil es da nicht viele relevanten Stellen gibt:

    Verzeichnis registrieren:
    Spoiler
    Code:
    private void register(Path dir) throws IOException {
     System.out.println("Überwache " + dir);
     WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
     
     keys.put(key, dir);
     }
    

    Event's abgreifen
    Spoiler
    Code:
    public void start() {
     while(true){
     System.out.println("New Package:");
     // wait for key to be signalled
     WatchKey key;
     try {
     key = watcher.take();
     } catch (InterruptedException x) {
     return;
     }
    
     Path dir = keys.get(key);
     if (dir == null) {
     System.err.println("WatchKey not recognized!!");
     continue;
     }
    
     for (WatchEvent<?> event: key.pollEvents()) {
     WatchEvent.Kind kind = event.kind();
     Path fullPath = dir.resolve((Path) event.context());
    
     this.processEvent(kind,fullPath);
     }
     
     }
    

    Event verarbeiten:
    Spoiler
    Code:
    private void processEvent(Kind kind, Path fullPath) {
     String fileName = fullPath.getFileName().toString();
     
     if("~".equals(fileName.substring(0,1))){
     return;
     }
     
     if(fullPath.toFile().isDirectory() == true){
     if(kind == StandardWatchEventKinds.ENTRY_CREATE){
     System.out.println("CREATE FOLDER" + fullPath);
     }
     
     if(kind == StandardWatchEventKinds.ENTRY_DELETE){
     System.out.println("DELETE FOLDER " + fullPath);
     }
    
     return;
     }else{
     if(kind == StandardWatchEventKinds.ENTRY_CREATE){
     System.out.println("CREATE " + fullPath);
     }
     
     if(kind == StandardWatchEventKinds.ENTRY_DELETE){
     System.out.println("DELETE " + fullPath);
     }
     
     if(kind == StandardWatchEventKinds.ENTRY_MODIFY){
     System.out.println("MODIFY " + fullPath);
     }
     }
     }
    


    An solch einen Algorithmus habe ich auch schon gedacht. Allerdings wie realisiert man das? Beim erstellen eines neuen Orders kann es je nach Benutzer gerne mal 5,6 Sekunden dauern bis der Name des Ordners eintippt hat. Dieses Delay ist variable und kann nicht im Code verwendet werden. Daher müsste ich ja zB alle Events 60 Sekunden lang sammeln und dann verarbeiten. Was aber wenn genau bei 59 Sekunden ein neuer Ordner erstellt wird der erst weitere 4 Sekunden später benanntn wird? Dann verarbeite ich bei 60 Sekunden die Event's und das Rename, bzw DELETE/CREATE fällt hinten runter.

    Natürlich könnte man hier sagen "Pech", aber das muss doch irgendwie elegant machbar sein.


    Danke schonmal für deine Antwort


    Gruß Blackb!rd
     
  6. 11. Juni 2013
    AW: SyncTool - Dateiüberwachung

    Laut diesen Threads kann man Renames mit dem WatchService nicht ohne weiteres überwachen bzw auswerten:
    java - Java7 WatchService - How to detect rename/move of the actual watched directory - Stack Overflow
    Java: File Renaming Detection - Stack Overflow

    Falls du keine andere Lösung findest, werden als Alternative zum WatchService jnotify (unterstützt Renames für Windows/Linux/Mac) und jpathwatch (Win/Linux) genannt.
     
  7. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.