Файл с измененным прослушивателем в Java

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

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

DefaultFileMonitor

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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.

Ответ 8

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

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

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

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

Ответ 9

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

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

Ответ 10

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

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

Ответ 12

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

Ответ 13

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

Ответ 14

Как и в других ответах, вот как я это сделал, используя File, Timer и 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);
    }

  }
}