题
我希望在文件系统中的文件发生更改时收到通知。除了一个轮询 LastModified File 属性的线程之外,我什么也没找到,显然这个解决方案不是最佳的。
解决方案
在较低水平来模拟此实用程序的唯一方法是对目录的线程轮询和保持关注这些文件的属性。但是你可以使用模式来开发这样一个实用程序适配器。
有关如Tomcat例如J2EE应用服务器等都有自动负载特征,其中在一旦部署描述符的变化或servlet类改变应用程序重新启动。
可以使用从这样的服务器库,因为大多数的Tomcat的代码的是可重复使用和开源。
其他提示
我已经写了前一个日志文件监视,而且我发现,轮询系统性能的影响,单个文件的属性,几次第二,其实是非常小的。
Java 7中,作为NIO.2的一部分加入了 WatchService API
在WatchService API被设计为需要被通知关于文件变更事件的应用程序。
我使用 Apache Commons 的 VFS API,下面是如何在不影响性能的情况下监视文件的示例:
Java commons-io 有一个 文件更改观察者. 。它与 FileAlterationMonitor 结合进行轮询。类似于公共VFS。优点是它的依赖性要少得多。
编辑:较少的依赖关系是不正确的,它们对于 VFS 来说是可选的。但它使用java File而不是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的文件系统操作可以对一些电脑慢,很容易影响应用程序的性能,如果没有处理好。
您也可以考虑在Apache共享JCI(Java编译器接口)。虽然这似乎API要聚焦的类动态编译,它也包括它的API,它监视文件的变化类。
Spring Integration 提供了一个很好的机制来监视目录和文件: 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);
}
}
}