Мені хотілося б отримати повідомлення, коли файл змінився у файловій системі. Я не знайшов нічого, крім потоку, який опитує властивість lastModified File, і явно це рішення не є оптимальним.
Мені хотілося б отримати повідомлення, коли файл змінився у файловій системі. Я не знайшов нічого, крім потоку, який опитує властивість lastModified File, і явно це рішення не є оптимальним.
Відповіді:
На низькому рівні єдиний спосіб моделювання цієї утиліти - це тематика опитування каталогів та збереження уваги за атрибутами файлу. Але ви можете використовувати шаблони для розробки адаптера для такої утиліти.
Наприклад, сервери додатків j2ee, такі як Tomcat та інші, мають функцію автоматичного завантаження, коли, як тільки дескриптор розгортання змінюється або клас сервлетів змінює додаток, перезапускається.
Ви можете використовувати бібліотеки з таких серверів, оскільки більшість кодів tomcat є багаторазовими і відкритими.
Я раніше писав монітор файлів журналів, і я виявив, що вплив на продуктивність системи опитування атрибутів одного файлу, кілька разів на секунду, насправді дуже малий.
Java 7 як частина NIO.2 додала API WatchService
API WatchService призначений для додатків, яким потрібно повідомити про події зміни файлів.
Я використовую API VFS від Apache Commons, ось приклад того, як слідкувати за файлом без особливого впливу на продуктивність:
Існує ліб під назвою jnotify, який обгортає ініціативу на Linux і також підтримує Windows. Ніколи не використовував його, і я не знаю, наскільки це добре, але варто спробувати.
У Java commons-io є FileAlterationObserver . це опитування в поєднанні з FileAlterationMonitor. Схожий на commons VFS. Перевага в тому, що він має набагато менше залежностей.
редагувати: менше залежностей не відповідає дійсності, вони є необов'язковими для 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
.
Ви можете прослуховувати зміни файлів за допомогою 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();
}
}
Якщо ви готові розлучитися з деякими грошима, JNIWrapper - це корисна бібліотека з Winpack, ви зможете отримати події файлової системи на певних файлах. На жаль, тільки вікна.
Дивіться https://www.teamdev.com/jniwrapper .
В іншому випадку вдаватися до нативного коду не завжди є поганою справою, особливо коли найкраща пропозиція - це механізм опитування, як проти рідної події.
Я помітив, що операції з файловою системою Java можуть бути повільними на деяких комп’ютерах і можуть легко вплинути на продуктивність програми, якщо не працювати з ними добре.
Ви також можете розглянути JCI Apache Commons (інтерфейс Java-компілятора). Хоча, схоже, цей API орієнтований на динамічну компіляцію класів, він також включає класи в свій API, який відстежує зміни файлів.
Весняна інтеграція забезпечує приємний механізм перегляду каталогів та файлів: http://static.springsource.org/spring-integration/reference/htmlsingle/#files . Досить впевнений, що це крос-платформа (я використовував її на Mac, Linux та Windows).
Існує комерційна бібліотека для настільних комп'ютерів для перегляду файлів і папок під назвою JxFileWatcher. Завантажити його можна звідси: http://www.teamdev.com/jxfilewatcher/
Також ви можете побачити це в дії в Інтернеті: http://www.teamdev.com/jxfilewatcher/onlinedemo/
Опитування останньої модифікованої властивості файлу є простим, але ефективним рішенням. Просто визначте клас, який розширює мій, 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();
}
Подібно до інших відповідей, ось як я це зробив за допомогою файлу, таймера та 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);
}
}
}