2013-04-21 29 views
23
import java.io.*; 
import java.nio.file.*; 

public class Tmp { 

    public static void main(String [] args) throws IOException { 
     int count = 0; 
     Path path = Paths.get("C:\\tmp\\"); 
     WatchService ws = null; 
     try { 
      ws = FileSystems.getDefault().newWatchService(); 
      path.register(ws, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, 
        StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 

     while(true) { 
      WatchKey key = null; 
      try { 
       key = ws.take(); 
      } catch(InterruptedException ie) { 
       ie.printStackTrace(); 
      } 

      for(WatchEvent<?> event: key.pollEvents()) { 
       switch(event.kind().name()) { 
        case "OVERFLOW": 
         System.out.println(++count + ": OVERFLOW"); 
         break; 
        case "ENTRY_MODIFY": 
         System.out.println(++count + ": File " + event.context() + " is changed!"); 
         break; 
        case "ENTRY_CREATE": 
         System.out.println(++count + ": File " + event.context() + " is created!"); 
         break; 
        case "ENTRY_DELETE": 
         System.out.println(++count + ": File " + event.context() + " is deleted!"); 
         break; 
        default: 
         System.out.println(++count + ": UNKNOWN EVENT!"); 
       } 
      } 

      key.reset(); 
     }  
    } 
} 

Bunu çalıştırmak ve ardından Not Defteri açıldı ++ ve ardından yeni bir boş dosya oluşturulur ve ben çıkış var C:\tmp\ dizinde a.txt olarak kaydedilir:WatchService neden bu kadar çok işlem yapıyor?

1: File a.txt is created! 
2: File a.txt is deleted! 
3: File a.txt is created! 

o neden? Dosya oluşturulduğu ve daha sonra silinip yeniden oluşturulduğu anlaşılıyor. Niye ya? Ben dosyadaki bazı metin koymak ve kaydedilmiş zaman çıkış

oldu:

4: File a.txt is changed! 
5: File a.txt is changed! 

Neden iki kez değişti?

+5

WatchService ile gördüğünüz davranışın Notepad ++ yolundan kaynaklandığını ve bazılarının Windows işletim sisteminin IO işlemleri gerçekleştirirken çalışma şeklini genişleteceğini düşünüyorum. "Standart" Windows not defteri gibi bir şey genellikle en beklenen davranışını ürettiğini buldum. Process Explorer'ı (http://technet.microsoft.com/en-gb/sysinternals/bb896653) kullanırsanız, şüpheleniyorum.Bir OS seviyesinde IO aktivitesini izlemek için aspx) aynı sonuçları göreceksiniz. –

+2

Bu, içerik ve meta veri yazmalarının ayrı ayrı gerçekleştirilmiş olmasından kaynaklanıyor olabilir. – afk5min

cevap

0

Dosya oluşturma ve silme olayları sistemimde doğru şekilde çalışıyor (Pencere 7 + 1.7.0_21).

değişiklik olayı mesajı

o dosya üzerinde her Ctrl + s operasyon için zamanın (n) sayısının görüntülenir.

 // Removed the "//" after director name as D://tmp" 
     //Added just to see the message with a 1 ms gap. 
     Thread.sleep(1000); // after key.reset(); 

Örnek: Biz dosyayı açın ve ctrl + s tuşuna devam ederse (değişikliklerle/herhangi bir değişiklik dışarı ile kaydedin). Her bir kayıt işlemi için aşağıdaki mesaj gösterilecektir (tekrar tekrar).

 File YourFileName.txt is changed! 

Sebep WatchService damgası yerine sağlama toplamı ile dosya değişikliklerini karşılaştırarak olduğunu pencerelerde olduğunu.

Daha açıklaması burada Platform dependencies

+0

Bu 1ms'lik bir boşluk değil, 1 saniyelik bir boşluk. Tabii ki tekrar kontrol etmeden önce bilgisayar terimlerinde çok uzun bir süre beklerseniz etkiyi görmeyeceksiniz. Buna gelince: "Neden Windows'ta WatchService, dosya değişikliklerini sağlama toplamı yerine zaman damgasıyla karşılaştırıyor." Ah ne? –

+0

@RobinGreen, Lütfen özel durumunuz ve cevabınız nedir? – VKPRO

0

verilen me

// get the first event before looping 
    WatchKey key = this.watcher.take(); 

    // reset key (executed twice but not invoke the polled events) 
    while (key != null && key.reset()) { 
     // polled events 
     for (final WatchEvent<?> event : key.pollEvents()) { 
     System.out.printf("\nGlobal received: %s, event for file: %s\n", event.kind(), 
      event.context()); 

     switch (event.kind().name()) { 
     case "ENTRY_CREATE": 
      LOGGER.debug("event ENTRY_CREATE"); 
      break; 
     case "ENTRY_DELETE": 
      LOGGER.debug("event ENTRY_DELETE"); 
      break; 
     case "ENTRY_MODIFY": 
      LOGGER.debug("event ENTRY_MODIFY"); 
      break; 
     default: 
      LOGGER.debug("event other [OVERFLOW]"); 
      break; 
     } 
     } 

     key = this.watcher.take(); 
    } 
1

İzle Servisi'nin Değiştir olay iki olayı oluşturur için bu çalışır. Varolan bir dosyayı değiştirdiğimizde, dosya sistemi önce onu 0 bayt ile oluşturur ve bir değişiklik olayı başlatır ve daha sonra üzerine veri yazar. Sonra değişiklik olayını tekrar ateşler. Bu yüzden iki değişiklik olayı gösteriyordu. Bu yüzden bu sorunu çözmek için ne yaptın, ben sadece bile

 Path path = null; 
     int count = 0; 

     try { 
      path = Paths.get(new Utility().getConfDirPath()); 
      System.out.println("Path: " + path); 
     } catch (UnsupportedEncodingException e1) { 
      e1.printStackTrace(); 
     } 

     WatchService watchService = null; 
     try { 
      watchService = FileSystems.getDefault().newWatchService(); 
      path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 


     while(true) { 
      WatchKey key = null; 
      try { 
       key = watchService.take(); 
      } catch(InterruptedException ie) { 
       ie.printStackTrace(); 
      } 

      for(WatchEvent<?> event: key.pollEvents()) { 
       switch(event.kind().name()) { 
        case "ENTRY_MODIFY": 
         System.out.println(++count + ": File " + event.context() + " is changed!"); 

         if (count%2==0) { 
          doOnChange(); // do whatever you want 
         } 
         break; 
        case "ENTRY_DELETE": 
         System.out.println(++count + ": File " + event.context() + " is deleted!"); 
         break; 
        default: 
         System.out.println(++count + ": UNKNOWN EVENT!"); 
       } 
      } 

      // reset the key 
      boolean valid = key.reset(); 
      if (!valid) { 
       System.out.println("Key has been unregistered"); 
      } 

     }  
0

Ben küçük FileWatcher Yardımcı Kütüphanesi oluşturdu saymak sadece bir kez tetiklenir edilmelidir Görevimi kontrol etmek sayaç kullanın: Bu olanak https://github.com/finsterwalder/fileutils

ödemesiz bir süre belirle. Ödemesiz dönem içindeki çoklu olaylar biriktirilir ve sadece bir kez tetiklenir.

Notepad ++ uygulamasının ne yaptığını bilmiyorsanız, denemeniz için Notepad ++ kullanmamalısınız. Notepad ++ aslında birkaç kez bir dosyaya yazıyor olabilir. Veya farklı bir ada sahip bir dosya yazabilir ve bittiğinde veya neyi isimlendirirse, yeniden adlandırabilir. Dosyaları değiştirmek ve izlemek için kendi kodunuzu yazın.

İlgili konular