我希望在文件系统中更改文件时收到通知。我只发现了一个轮询lastModified File属性的线程,显然这个解决方案并不是最优的。Java中的文件更改监听器
回答
在较低水平来模拟此实用程序的唯一方法是对目录的线程轮询和保持关注这些文件的属性。但是,您可以使用模式为这种实用程序开发适配器。
例如J2EE应用服务器,如Tomcat和其他人有一个自动加载功能在哪里,只要部署描述符的变化或Servlet类更改应用程序重新启动。
您可以使用这些服务器的库,因为tomcat的大部分代码都是可重用的并且是开源的。
这在Java 7中不再是这样了:现在有一个API可以挂载到操作系统的通知服务中:http://blogs.oracle.com/thejavatutorials/entry/watching_a_directory_for_changes – 2011-09-29 10:00:06
这个API非常不适合,它没有在Linux上提供关于文件关闭事件的通知。所以,给定一个简单的例子,当一个文件关闭时,将它复制到另一个目录不起作用。 – 2013-12-16 18:56:40
如果你愿意与一些钱JNIWrapper到部分与Winpack有用的库,你将能够获得对某些文件的文件系统事件。不幸的是窗户只。
http://www.teamdev.com/jniwrapper/index.jsf
,否则诉诸本地代码并不总是一件坏事,尤其是当所提供的最好的是轮询机制作为对本地事件。
我注意到的java文件系统的操作可以对一些电脑慢,很容易影响应用程序的性能,如果没有处理好。
我之前写的日志文件监测器,我发现,轮询一个文件的属性,几次一秒钟的系统性能的影响,实际上是非常小的。
Java 7中,为NIO.2的部分加入了WatchService API
的WatchService API是专为需要通知有关文件更改事件的应用程序。
“更多NIO功能”具有文件监视功能,实现取决于底层操作系统。应该在JDK7中。
我使用Apache的百科全书的VFS API,这里是如何监视性能没有太大影响的文件的例子:
有文件和文件夹商用跨桌面的库看着叫JxFileWatcher。 它可以从这里下载: http://www.teamdev.com/jxfilewatcher/
还可以看到它在行动在线: http://www.teamdev.com/jxfilewatcher/onlinedemo/
您也可以考虑在Apache下议院JCI(Java编译器接口)。尽管这个API似乎专注于类的动态编译,但它也包括API的类中监视文件更改的类。
Spring集成提供看目录和文件的一个很好的机制:http://static.springsource.org/spring-integration/reference/htmlsingle/#files。很确定它是跨平台的(我在mac,linux和windows上使用过它)。
我每次去阅读属性文件时都会运行这段代码,如果自上次读取文件后修改了文件,实际上只会读取该文件。希望这可以帮助某人。
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
中使用了类似的方法。
Java commons-io有一个FileAlterationObserver。它结合FileAlterationMonitor进行轮询。类似于普通的VFS。好处是它具有更少的依赖性。
编辑:减少依赖关系不成立,它们对于VFS是可选的。但它使用java File而不是VFS抽象层。
您可以使用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();
}
}
轮询示例中的最后一次修改文件属性是一个简单而有效的解决方案,但。只要定义一个类扩展我的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);
}
}
}
- 1. 监听文件夹的更改java
- 2. 属性Java中的文件监听器?
- 3. java属性更改监听器
- 4. Java JComboBox监听更改选择事件
- 5. MySQL表更改的事件监听器?
- 6. ABAddressBook更改监听器
- 7. JQuery URL更改监听器
- 8. Android AsyncTask - 更改监听器
- 9. 汇合atlassian更改事件监听器
- 10. 事件监听器更改按钮
- 11. Dart lang中的DOM更改监听器
- 12. 更改收集器上的监听器(显然是监听模型更改)
- 13. 监视文件更改Java
- 14. 系统如何监听文件更改?
- 15. 创建事件监听器,监听变量中的值是否已更改
- 16. Java MySQL事件监听器
- 17. Java事件监听器
- 18. Java中Redis的监听器
- 19. Java - Swing中的监听器
- 20. java中的事件监听器
- 21. 了解java中的事件监听器
- 22. Java中的事件监听器
- 23. Java中的事件和监听器
- 24. Java事件监听器在时钟上分钟更改
- 25. 在CallLog.Calls中监听更改
- 26. JTextField监听器,用于修改textField文本的文本更改
- 27. 更改应用程序配置/资源文件的监听器
- 28. 将值更改为JTextField的监听器
- 29. 图库内容更改的监听器
- 30. Java JList监听器
感谢您的回复。由于我的需求很小(我只需要重新加载一个属性文件在我的web应用程序中已更改...主要是因为重新启动整个webapp有点慢),我会坚持使用投票模式。至少现在我知道这些案例没有简单的解决方案。 – cheng81 2009-01-30 10:44:10
只是一个说明。在我们发现大文件趋于缓慢进入之前,我们解决了这个问题之后,轮询机制在完全写入之前通常会发现新文件或更改文件。为了解决这个问题,采取了“两口”解决方案。轮询者注意到一个文件已经改变,但没有通知系统一个新的/已更改的文件,直到两个轮询看起来相同:即已经稳定。治愈了很多错误文件错误。 – 2012-02-22 11:23:04
另一方面,Tomcat在将大型WAR文件从远程源文件放入webapps文件夹时遇到了这个问题,并且很长一段时间都这样做了。 – 2015-04-30 11:47:45