जावा में फ़ाइल श्रोता बदल दिया


104

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


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

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

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

जवाबों:


21

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

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

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


59
: यह नहीं रह गया है जावा 7 में सत्य है: वहाँ अब है कि ओएस की अधिसूचना सेवाओं में हुक कर सकते हैं इस के लिए एक API blogs.oracle.com/thejavatutorials/entry/...
Arnout Engelen

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

117

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

Java 7, NIO.2 के भाग के रूप में WatchService API को जोड़ा गया है

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


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

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


39

मैं अपाचे कॉमन्स से वीएफएस एपीआई का उपयोग करता हूं, यहां एक उदाहरण है कि प्रदर्शन में बहुत प्रभाव के बिना किसी फ़ाइल की निगरानी कैसे करें:

DefaultFileMonitor


27

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


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

8

Java commons-io में FileAlterationObserver है । यह FileAlterationMonitor के संयोजन में मतदान करता है। कॉमन्स VFS के समान। द आफगोर यह है कि इसकी निर्भरता बहुत कम है।

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


4

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


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

यह पैकेज लगता है java.nio.file। एक ट्यूटोरियल देखें ।
डेविड एल।

4

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

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


2

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

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

2

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

Https://www.teamdev.com/jniwrapper देखें ।

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

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


1

आप Apache Commons JCI (Java Compiler Interface) पर भी विचार कर सकते हैं। हालाँकि यह एपीआई कक्षाओं के गतिशील संकलन पर केंद्रित है, लेकिन इसमें इसके एपीआई में कक्षाएं भी शामिल हैं जो फ़ाइल परिवर्तनों की निगरानी करती हैं।

उदाहरण: http://commons.apache.org/jci/usage.html


1

स्प्रिंग इंटीग्रेशन निर्देशिकाएँ और फ़ाइलों को देखने के लिए एक अच्छा तंत्र प्रदान करता है: http://static.springsource.org/spring-integration/reference/htmlsingle/#files । बहुत यकीन है कि यह क्रॉस प्लेटफॉर्म है (मैंने इसे मैक, लिनक्स, और विंडोज़ पर इस्तेमाल किया है)।


1

JxFileWatcher नामक फ़ाइलों और फ़ोल्डरों के लिए एक व्यावसायिक क्रॉस-डेस्कटॉप लाइब्रेरी है। इसे यहाँ से डाउनलोड किया जा सकता है: http://www.teamdev.com/jxfilewatcher/

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


1

अंतिम संशोधित फ़ाइल संपत्ति को मतदान करना हालांकि एक सरल लेकिन प्रभावी उपाय है। बस मेरी फैली हुई एक कक्षा को परिभाषित करें 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

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

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);
    }

  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.