Файл изменен слушатель в Java



Я хотел бы получать уведомления, когда файл был изменен в файловой системе. Я не нашел ничего, кроме потока, который опрашивает свойство lastModified File, и ясно, что это решение не является оптимальным.

637   14  

14 ответов:

на низком уровне единственным способом моделирования этой утилиты является опрос потока в каталоге и наблюдение за атрибутами файла. Но вы можете использовать шаблоны для разработки адаптера для такой утилиты.

например, серверы приложений j2ee, такие как Tomcat и другие, имеют функцию автоматической загрузки, где при изменении дескриптора развертывания или класса сервлета приложение перезапускается.

вы можете использовать библиотеки с таких серверов, как большинство код tomcat является многоразовым и открытым исходным кодом.

Я уже писал монитор файлов журнала раньше, и я обнаружил, что влияние на производительность системы опроса атрибутов одного файла, несколько раз в секунду, на самом деле очень мало.

Java 7, как часть NIO.2 добавил WatchService API

API WatchService предназначен для приложений, которым необходимо получать уведомления о событиях изменения файлов.

Я использую API VFS от Apache Commons, вот пример того, как контролировать файл без особого влияния на производительность:

DefaultFileMonitor

есть lib называется jnotify, который обертывает inotify на linux и имеет также поддержку для windows. Никогда не использовал его, и я не знаю, насколько это хорошо, но это стоит попробовать, я бы сказал.

Java commons-io имеет FileAlterationObserver. он делает опрос в сочетании с FileAlterationMonitor. Похоже на commons VFS. Преимущество заключается в том, что он имеет гораздо меньше зависимостей.

изменить: меньше зависимостей-это не правда, они не являются обязательными для ВФС. Но он использует java-файл вместо уровня абстракции VFS.

"дополнительные функции NIO" имеет функцию просмотра файлов, реализация которой зависит от базовой ОС. Должно быть в JDK7.

Я запускаю этот фрагмент кода каждый раз, когда я иду читать файл свойств, только на самом деле читая файл, если он был изменен с момента последнего чтения. Надеюсь, это кому-то поможет.

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.

Если вы готовы расстаться с некоторыми деньгами JNIWrapper является полезной библиотекой с Winpack, вы сможете получить события файловой системы на определенных файлах. К сожалению, только windows.

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

в противном случае, прибегая к машинному коду не всегда плохо, особенно когда лучшее предложение-это механизм опроса по сравнению с собственным событием.

Я заметил, что операции файловой системы java могут быть медленными на некоторых компьютеры и может легко повлиять на производительность приложений, если не обрабатываются хорошо.

вы также можете рассмотреть Apache Commons JCI (Java Compiler Interface). Хотя этот API, по-видимому, ориентирован на динамическую компиляцию классов, он также включает классы в свой API, который отслеживает изменения файлов.

пример: http://commons.apache.org/jci/usage.html

Весенняя интеграция обеспечивает хороший механизм для просмотра каталогов и файлов:http://static.springsource.org/spring-integration/reference/htmlsingle/#files. довольно уверен, что это кросс-платформенный (я использовал его на mac, linux и windows).

вы можете прослушивать изменения файлов с помощью 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();
    }
}

существует коммерческая кросс-настольная библиотека для просмотра файлов и папок под названием JxFileWatcher. Его можно скачать отсюда: http://www.teamdev.com/jxfilewatcher/

также вы можете увидеть его в действии онлайн: http://www.teamdev.com/jxfilewatcher/onlinedemo/

Как и другие ответы, вот как я сделал это с помощью файла, таймера и 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);
    }

  }
}

опрос последнего измененного свойства файла является простым, но эффективным решением. Просто определите класс, расширяющий my 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();
}

Comments

    Ничего не найдено.