2013-04-21 9 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(); 
     }  
    } 
} 

जब मैं इस चलाने के लिए और फिर नोटपैड खोला ++ और फिर एक नई खाली फ़ाइल बनाया है और C:\tmp\ निर्देशिका में a.txt के रूप में यह बचाया मैं उत्पादन मिल गया:वॉच सर्विस सेवा इतने सारे ऑपरेशन क्यों उत्पन्न करता है?

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

कि क्यों है? ऐसा लगता है कि फ़ाइल बनाई गई थी और फिर हटा दी गई और फिर फिर से बनाई गई। क्यूं कर?

जब मैं फ़ाइल में कुछ पाठ रखा और बचाया यह उत्पादन किया गया था:

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

इसे दो बार क्यों बदल दिया?

+5

मुझे लगता है कि आप WatchService के साथ जो व्यवहार देख रहे हैं वह नोटपैड ++ के रास्ते के कारण है और कुछ आईओ ऑपरेशंस करते समय विंडोज ऑपरेटिंग सिस्टम काम करता है। मैंने पाया है कि "मानक" विंडोज नोटपैड की तरह कुछ आमतौर पर सबसे अधिक अपेक्षित व्यवहार उत्पन्न करता है। मुझे संदेह है कि यदि आप प्रोसेस एक्सप्लोरर (http://technet.microsoft.com/en-gb/sysinternals/bb896653 का उपयोग करते हैं।एएसपीएक्स) एक ओएस स्तर पर आईओ गतिविधि की निगरानी करने के लिए आप एक ही परिणाम देखेंगे। –

+2

यह इस तथ्य के कारण हो सकता है कि सामग्री और मेटाडाटा लिखने को अलग से किया जाता है। – afk5min

उत्तर

0

फ़ाइल निर्माण और हटाना घटनाएं मेरे सिस्टम (विंडो 7 + 1.7.0_21) में सही तरीके से काम कर रही हैं।

परिवर्तन घटना संदेश प्रत्येक Ctrl +कि फाइल पर ऑपरेशन के लिए समय के (एन) की संख्या प्रदर्शित किया जाता है।

 // 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(); 

उदाहरण: यदि हम फ़ाइल को खोलने और दबाने Crtl + रों पर रखने (साथ बचाने के किसी भी परिवर्तन बाहर/परिवर्तन के साथ)। प्रत्येक संदेश ऑपरेशन के लिए निम्न संदेश प्रदर्शित होगा (बार-बार)।

 File YourFileName.txt is changed! 

कारण विंडोज़ में है वॉच सर्विस सेवा की बजाय टाइमस्टैम्प के साथ फ़ाइल परिवर्तनों की तुलना कर रहा है।

अधिक विवरण यहां Platform dependencies

+0

यह 1 एमएमएस अंतर नहीं है, यह 1 सेकंड का अंतर है। बेशक आप फिर से जांचने से पहले कंप्यूटर शर्तों में बहुत लंबे समय तक प्रतीक्षा करने पर प्रभाव नहीं देखेंगे। इसके लिए: "विंडोज़ में कारण है वॉच सर्विस सर्विस की तुलना में टाइमसमैम्प के साथ फ़ाइल परिवर्तनों की तुलना कर रहा है।" ओह क्या? –

+0

@ रॉबिनग्रीन, कृपया मुझे बताएं कि आपका अपवाद क्या है और आपका उत्तर क्या है। – VKPRO

0

दिया मुझे

// 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

घड़ी सेवा का संशोधित घटना दो घटनाओं उत्पन्न करता है के लिए इस काम करता है। जब हम पहले से मौजूद फाइल को संशोधित करते हैं, तो फ़ाइल सिस्टम पहले इसे 0 बाइट्स बनाता है और एक संशोधित घटना को सक्रिय करता है और फिर उस पर डेटा लिखता है। फिर यह संशोधित घटना को फिर से निकाल देता है। यही कारण है कि यह दो संशोधित घटनाओं को दिखा रहा था। तो क्या मैं इस समस्या को हल करने के लिए किया है, मैं बस अपना काम की जांच करने के काउंटर का उपयोग केवल एक बार पर शुरू किया जा चाहिए भी गिनती

 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

मैं एक छोटे से FileWatcher उपयोगिता पुस्तकालय बनाया: https://github.com/finsterwalder/fileutils

यह करने की अनुमति देता एक अनुग्रह अवधि निर्धारित करें। अनुग्रह अवधि के अंदर कई घटनाएं जमा की जाती हैं और केवल एक बार ट्रिगर होती हैं।

आपको अपने प्रयोगों के लिए नोटपैड ++ का उपयोग नहीं करना चाहिए, क्योंकि आप नहीं जानते कि नोटपैड ++ क्या कर रहा है। ऐसा हो सकता है कि नोटपैड ++ वास्तव में कई बार फ़ाइल में लिख रहा है। या यह एक अलग नाम के साथ एक फाइल लिख सकता है और जब इसे किया या क्या नहीं, इसका नाम बदल सकते हैं। फ़ाइलों को हेरफेर करने और उसे देखने के लिए अपना स्वयं का कोड लिखें।

संबंधित मुद्दे