Java中的文件已更改侦听器
我希望在文件系统中更改文件时收到通知。 我没有发现什么,只是一个线程轮询lastmodified文件属性,显然这个解决scheme是不是最佳的。
在低级别上,build立这个实用程序的唯一方法是在一个目录上进行线程轮询,并监视该文件的属性。 但是你可以使用模式来开发这样一个实用程序的适配器。
例如像Tomcat和其他的j2ee应用程序服务器有一个自动加载function,一旦部署描述符改变或servlet类改变,应用程序重新启动。
你可以使用这些服务器的库,因为tomcat的大部分代码都是可重用的,并且是开源的。
我以前写过一个日志文件监视器,我发现每秒几次轮询单个文件的属性对系统性能的影响实际上是非常小的。
作为NIO.2的一部分,Java 7增加了WatchService API
WatchService API是为需要通知文件更改事件的应用程序devise的。
我使用来自Apache Commons的VFS API,下面是一个如何监视文件而不影响性能的例子:
DefaultFileMonitor
有一个名为jnotify的lib,在linux上包装inotify并且还支持windows。 从来没有使用它,我不知道它有多好,但值得一试我会说。
Java commons-io有一个FileAlterationObserver 。 它结合FileAlterationMonitor进行轮询。 类似于普通的VFS。 有利的是,它具有更less的依赖性。
编辑:减less依赖关系是不正确的,他们是可选的VFS。 但它使用java File而不是VFS抽象层。
“更多的NIOfunction”具有文件监视function,实现依赖于底层操作系统。 应该在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的有用的库,你将能够获得某些文件上的文件系统事件。 不幸的是窗户只。
http://www.teamdev.com/jniwrapper/index.jsf
否则,诉诸本地代码并不总是一件坏事,特别是当提供最好的轮询机制而不是本地事件时。
我注意到,在某些计算机上,java文件系统操作可能会很慢,如果处理不好,很容易影响应用程序的性能。
您也可以考虑Apache Commons JCI(Java编译器接口)。 虽然这个API似乎专注于类的dynamic编译,但是它的API中也包含了监视文件变化的类。
例如: http : //commons.apache.org/jci/usage.html
Spring Integration为观察目录和文件提供了一个很好的机制: 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/
类似于其他的答案,这里是我如何使用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); } } }
轮询最后修改的文件属性是一个简单而有效的解决scheme。 只需定义一个扩展我的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(); }