Frage

Ich möchte benachrichtigt werden, wenn eine Datei im Dateisystem geändert wurde. Ich habe nichts anderes als einen Thread gefunden, fragt die lastModified Datei-Eigenschaft und eindeutig diese Lösung nicht optimal ist.

War es hilfreich?

Lösung

Auf dem niedrigen Niveau der einzige Weg, um dieses Dienstprogramm zu modellieren ist ein Thread Polling auf ein Verzeichnis haben und eine Uhr auf die Attribute der Datei zu halten. Aber Sie können Muster verwenden, um einen Adapter für ein solches Programm zu entwickeln.

Zum Beispiel J2EE-Anwendungsserver wie Tomcat und andere haben eine automatische Last Funktion, wo in so bald wie Deployment Descriptor Änderungen oder Servlet-Klasse ändert die Anwendung neu gestartet wird.

Sie können die Bibliotheken von solchen Servern verwenden, da die meisten der Code von tomcat wiederverwendbar und Open Source ist.

Andere Tipps

Ich habe vor ein Logfile-Monitor geschrieben, und ich fand, dass die Auswirkungen auf die Systemleistung von Polling die Attribute einer einzelnen Datei, nur ein paar Mal pro Sekunde, eigentlich sehr klein ist.

Java 7 als Teil NIO.2 hat die WatchService API hinzugefügt

  

Die WatchService API ist für Anwendungen, die über Dateiänderungsereignisse informiert werden müssen.

ich die VFS API von Apache Commons verwenden, hier ist ein Beispiel dafür, wie eine Datei ohne vielen Einfluss in der Leistung zu überwachen:

DefaultFileMonitor

Es gibt eine lib genannt jnotify das hüllt inotify auf linux und auch für Windows unterstützt hat. Nie benutzt es und ich weiß nicht, wie gut es ist, aber es ist einen Versuch wert, würde ich sagen.

Sie können Dateiänderungen mit einem Filereader hören. Plz siehe Beispiel unten

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

Wenn Sie bereit sind, mit etwas Geld zu trennen, JNIWrapper ist eine nützliche Bibliothek mit einem Winpack, werden Sie in der Lage sein, um Dateisystemereignisse auf bestimmte Dateien. Leider Fenster nur.

Siehe https://www.teamdev.com/jniwrapper .

Ansonsten zu nativem Code zurückzugreifen, ist nicht immer eine schlechte Sache vor allem, wenn die besten Angebote ein Abfragemechanismus gegenüber einem nativen Ereignisse ist.

Ich habe bemerkt, dass Java Dateisystemoperationen auf einigen Computern langsam sein kann und die Leistung leicht beeinflussen kann die Anwendung, wenn nicht gut behandelt.

Sie können auch die Apache Commons JCI (Java Compiler Interface) in Betracht ziehen. Obwohl diese API auf dynamische Zusammenstellung von Klassen konzentriert zu sein scheint, es enthält auch Klassen in der API, die Dateiänderungen überwacht.

Beispiel: http://commons.apache.org/jci/usage.html

Frühling Integration bietet einen schönen Mechanismus für Verzeichnisse und Dateien zu beobachten: http: / /static.springsource.org/spring-integration/reference/htmlsingle/#files . Ziemlich sicher, es ist Cross-Plattform (ich habe es auf dem Mac verwendet, Linux und Windows).

Es ist eine kommerzielle Cross-Desktop-Bibliothek für Dateien und Ordner namens JxFileWatcher beobachten. Es kann hier heruntergeladen werden: http://www.teamdev.com/jxfilewatcher/

Sie können auch sie in Action-Online sehen:   http://www.teamdev.com/jxfilewatcher/onlinedemo/

Polling die letzte geänderte Datei Eigenschaft ist eine einfache, aber effektive Lösung though. Definieren Sie einfach eine Klasse meine FileChangedWatcher erstreckt und die onModified() Methode implementieren:

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

ähnlich wie bei den anderen Antworten, hier ist, wie ich tat es mit der Datei, Timer und Timertask diesen Lauf als Hintergrund-Thread Polling in festgelegten Intervallen zu lassen.

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

  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top