2009-01-30 8 views
91

फ़ाइल सिस्टम में फ़ाइल बदल दी गई है, तो मैं अधिसूचित होना चाहता हूं। मुझे एक थ्रेड के अलावा कुछ भी नहीं मिला है जो अंतिम संशोधित फ़ाइल संपत्ति का चुनाव करता है और स्पष्ट रूप से यह समाधान इष्टतम नहीं है।फ़ाइल में बदल गया श्रोता जावा

+0

सभी प्रतिक्रियाओं के लिए धन्यवाद। चूंकि मेरी ज़रूरतें छोटी हैं (मुझे केवल अपने वेब एप्लिकेशन में बदले में एक प्रॉपर्टी फाइल को फिर से लोड करने की ज़रूरत है ... मुख्य रूप से पूरे वेबपैप को पुनरारंभ करना थोड़ी धीमी है), मैं चुनाव मॉडल के साथ रहूंगा। कम से कम अब मुझे पता है कि इस मामले के मामलों के लिए कोई आसान समाधान नहीं है। – cheng81

+13

बस एक नोट। जब हमने पाया कि बड़ी फाइलें धीरे-धीरे आती हैं, तो हमने इस समस्या को हल किया, और मतदान तंत्र को पूरी तरह से लिखा जाने से पहले एक नई या बदली गई फ़ाइल की खोज की गई। इसे हल करने के लिए 'दो काटने' समाधान अपनाया गया था। परामर्शदाता ने देखा कि एक फाइल बदल गई है, लेकिन एक नई/बदली गई फाइल की प्रणाली को तब तक सूचित नहीं किया जब तक कि यह दो चुनावों के लिए समान नहीं था: यानी स्थिर हो गया था। बहुत सारी खराब त्रुटियों को ठीक किया। –

+1

एक तरफ, टोमकैट को उस समस्या का सामना करना पड़ता है जब बड़ी WAR फ़ाइलों को दूरस्थ स्रोतों से वेबपैस फ़ोल्डर में छोड़ दिया जाता है और लंबे समय तक ऐसा किया जाता है। –

उत्तर

19

निम्न स्तर पर इस उपयोगिता को मॉडल करने का एकमात्र तरीका निर्देशिका पर थ्रेड मतदान करना और फ़ाइल के गुणों पर नजर रखना है। लेकिन आप इस तरह की उपयोगिता के लिए एडाप्टर विकसित करने के लिए पैटर्न का उपयोग कर सकते हैं।

उदाहरण के लिए जे 2 ई एप्लिकेशन सर्वर जैसे टोमकैट और अन्य लोगों के पास एक ऑटो लोड सुविधा है जहां जैसे ही तैनाती डिस्क्रिप्टर परिवर्तन या सर्वलेट क्लास में एप्लिकेशन पुनरारंभ होता है।

आप ऐसे सर्वरों से पुस्तकालयों का उपयोग कर सकते हैं क्योंकि अधिकांश टोमकैट कोड को पुन: प्रयोज्य और ओपनसोर्स है।

+54

यह जावा 7 में अब सत्य नहीं है: इसके लिए अब एक एपीआई है जो ओएस की अधिसूचना सेवाओं में शामिल हो सकती है: http://blogs.oracle.com/thejavatutorials/entry/watching_a_directory_for_changes –

+0

वह एपीआई बेहद अपर्याप्त है, यह नहीं है लिनक्स पर फ़ाइल बंद घटनाओं के लिए अधिसूचना प्रदान करें। इसलिए, एक साधारण मामला दिया गया है, जब एक फ़ाइल बंद हो जाती है, तो इसे दूसरी निर्देशिका में कॉपी करें काम नहीं करता है। –

2

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

http://www.teamdev.com/jniwrapper/index.jsf

अन्यथा, मूल कोड का सहारा हमेशा एक बुरी बात है, खासकर जब प्रस्ताव पर सबसे अच्छा एक देशी घटना के खिलाफ के रूप में एक मतदान तंत्र है नहीं है ।

मैंने देखा है कि जावा कंप्यूटर सिस्टम ऑपरेशंस कुछ कंप्यूटरों पर धीमा हो सकता है और यदि अच्छी तरह से संभाला नहीं जाता है तो एप्लिकेशन प्रदर्शन को आसानी से प्रभावित कर सकता है।

27

jnotify नामक एक lib है जो लिनक्स पर inotify लपेटता है और विंडोज़ के लिए भी समर्थन करता है। कभी इसका इस्तेमाल नहीं किया और मुझे नहीं पता कि यह कितना अच्छा है, लेकिन यह एक कोशिश के लायक है जो मैं कहूंगा।

+1

यह उपयोग करने के लिए पूरी तरह से और सुपर सरल काम करता है। मैं कई वर्षों से inotify का उपयोग कर रहा हूँ। यह तेज़, स्थिर और भरोसेमंद –

102

मैंने पहले एक लॉग फ़ाइल मॉनिटर लिखा है, और मैंने पाया कि एक फ़ाइल के गुणों को मतदान करने के सिस्टम प्रदर्शन पर प्रभाव, एक सेकंड में कुछ बार, वास्तव में बहुत छोटा है।

जावा 7, NIO.2 का हिस्सा WatchService API

WatchService एपीआई अनुप्रयोगों फ़ाइल परिवर्तन की घटनाओं के बारे में सूचित करने की आवश्यकता है के लिए डिज़ाइन किया गया है के रूप में जोड़ा गया है।

+7

है, उदाहरणों को मैं निर्देशिका देखने के रूप में देखता हूं, लेकिन एक व्यक्तिगत फ़ाइल के बारे में क्या? –

+0

@ArchimedesTrajano एपीआई आपको सूचित करता है जब निर्देशिका में एक फ़ाइल बदल गई है। ट्रिगर होने वाली घटना में फ़ाइल का नाम बदल गया है जो बदल गया है। तो आप किसी निश्चित फ़ाइल या फ़ाइलों के लिए ईवेंट को संभाल सकते हैं और दूसरों को अनदेखा कर सकते हैं। – Michael

+0

@ArchimedesTrajano https://stackoverflow.com/questions/16251273/can-i-watch-for-single-file-change-with-watchservice-not-the-whole-directory – user1742529

3

"अधिक एनआईओ फीचर्स" में फाइल घड़ी की कार्यक्षमता है, अंतर्निहित ओएस पर निर्भर कार्यान्वयन के साथ। जेडीके 7 में होना चाहिए।

DefaultFileMonitor

+0

क्या आप अधिक विशिष्ट हो सकते हैं या एक लिंक पोस्ट कर सकते हैं दस्तावेज़ीकरण के लिए? इस पर कुछ भी नहीं मिल रहा है ... – Luciano

37

मैं अपाचे कॉमन्स से वीएफएस एपीआई का उपयोग है, तो यहां प्रदर्शन में ज्यादा प्रभाव के बिना एक फ़ाइल की निगरानी के लिए एक उदाहरण है JxFileWatcher कहा जाता है। यह यहाँ से डाउनलोड किया जा सकता है: http://www.teamdev.com/jxfilewatcher/

इसके अलावा, आप यह कार्रवाई ऑनलाइन में देख सकते हैं: http://www.teamdev.com/jxfilewatcher/onlinedemo/

+1

इस उत्तर के लिए धन्यवाद!वास्तव में मैंने जो खोजा है ... –

+0

बहुत उपयोगी, धन्यवाद –

1

फ़ाइलों और फ़ोल्डरों के लिए एक वाणिज्यिक पार डेस्कटॉप पुस्तकालय है:

1

तुम भी अपाचे कॉमन्स जेसीआई (जावा संकलक इंटरफ़ेस) विचार कर सकते हैं। यद्यपि यह एपीआई कक्षाओं के गतिशील संकलन पर केंद्रित है, लेकिन इसमें एपीआई में कक्षाएं भी शामिल हैं जो फ़ाइल परिवर्तनों पर नज़र रखती हैं।

उदाहरण: http://static.springsource.org/spring-integration/reference/htmlsingle/#files: http://commons.apache.org/jci/usage.html

1

स्प्रिंग एकता निर्देशिकाएँ और फ़ाइलों को देखने के लिए एक अच्छा तंत्र प्रदान करता है। बहुत यकीन है कि यह क्रॉस प्लेटफ़ॉर्म है (मैंने इसे मैक, लिनक्स और विंडोज़ पर उपयोग किया है)।

3

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

private long timeStamp; 
private File file; 

private boolean isFileUpdated(File file) { 
    this.file = file; 
    this.timeStamp = file.lastModified(); 

    if(this.timeStamp != timeStamp) { 
    this.timeStamp = timeStamp; 
    //Yes, file is updated 
    return true; 
    } 
    //No, file is not updated 
    return false; 
} 

इसी तरह का दृष्टिकोण Log4J FileWatchdog में उपयोग किया जाता है।

7

जावा कॉमन्स-आईओ में FileAlterationObserver है। यह FileAlterationMonitor के साथ संयोजन में मतदान करता है। कॉमन्स वीएफएस के समान। फायदेमंद यह है कि इसमें बहुत कम निर्भरताएं हैं।

संपादित करें: कम निर्भरता सत्य नहीं है, वे VFS के लिए वैकल्पिक हैं। लेकिन यह वीएफएस अबास्ट्रक्शन परत के बजाय जावा फ़ाइल का उपयोग करता है।

1

आप फ़ाइल रीडर का उपयोग कर फ़ाइल परिवर्तन सुन सकते हैं। कृपया नीचे दिए गए उदाहरण को देखें

// File content change listener 
private String fname; 
private Object lck = new Object(); 
... 
public void run() 
{ 
    try 
    { 
     BufferedReader br = new BufferedReader(new FileReader(fname)); 
     String s; 
     StringBuilder buf = new StringBuilder(); 
     while(true) 
     { 
      s = br.readLine(); 
      if(s == null) 
      { 
       synchronized(lck) 
       { 
        lck.wait(500); 
       } 
      } 
      else 
      { 
       System.out.println("s = " + s); 
      } 

     } 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 
0

अंतिम संशोधित फ़ाइल प्रॉपर्टी को मतदान करना एक सरल लेकिन प्रभावी समाधान है। बस एक वर्ग मेरी FileChangedWatcher विस्तार को परिभाषित करने और onModified() तरीका लागू:

import java.io.File; 

public abstract class FileChangedWatcher 
{ 
    private File file; 

    public FileChangedWatcher(String filePath) 
    { 
     file = new File(filePath); 
    } 

    public void watch() throws InterruptedException 
    { 
     long currentModifiedDate = file.lastModified(); 

     while (true) 
     { 
      long newModifiedDate = file.lastModified(); 

      if (newModifiedDate != currentModifiedDate) 
      { 
       currentModifiedDate = newModifiedDate; 
       onModified(); 
      } 

      Thread.sleep(100); 
     } 
    } 

    public String getFilePath() 
    { 
     return file.getAbsolutePath(); 
    } 

    protected abstract void onModified(); 
} 
0

अन्य उत्तर की तरह, यहाँ है मैं इसे का उपयोग कर फ़ाइल, टाइमर, और TimerTask सेट अंतराल पर एक पृष्ठभूमि धागा मतदान के रूप में इस चलने देने के लिए कैसे किया ।

import java.io.File; 
import java.util.Timer; 
import java.util.TimerTask; 

public class FileModifiedWatcher 
{ 
    private static File file; 
    private static int pollingInterval; 
    private static Timer fileWatcher; 
    private static long lastReadTimeStamp = 0L; 

    public static boolean init(String _file, int _pollingInterval) 
    { 
    file = new File(_file); 
    pollingInterval = _pollingInterval; // In seconds 

    watchFile(); 

    return true; 
    } 

    private static void watchFile() 
    { 
    if (null == fileWatcher) 
    { 
     System.out.println("START"); 

     fileWatcher = new Timer(); 

     fileWatcher.scheduleAtFixedRate(new TimerTask() 
     { 
     @Override 
     public void run() 
     { 

      if (file.lastModified() > lastReadTimeStamp) 
      { 
      System.out.println("File Modified"); 
      } 

      lastReadTimeStamp = System.currentTimeMillis(); 
     } 
     }, 0, 1000 * pollingInterval); 
    } 

    } 
}