我希望在文件系统中更改文件时收到通知。我找到的只是一个调查lastModified File属性的线程,显然这个解决方案不是最佳的。
答案 0 :(得分:110)
之前我写过一个日志文件监视器,我发现轮询单个文件属性的系统性能每秒几次,实际上非常小。
作为NIO.2的一部分,Java 7添加了WatchService API
WatchService API专为需要通知文件更改事件的应用程序而设计。
答案 1 :(得分:39)
我使用Apache Commons的VFS API,这是一个如何监控文件而不会对性能产生太大影响的示例:
答案 2 :(得分:27)
答案 3 :(得分:21)
在低级别,建模此实用程序的唯一方法是在目录上进行线程轮询并密切关注文件的属性。但您可以使用模式为这样的实用程序开发适配器。
例如,像Tomcat这样的j2ee应用程序服务器具有自动加载功能,只要部署描述符发生更改或servlet类更改,应用程序就会重新启动。
您可以使用来自此类服务器的库,因为tomcat的大部分代码都是可重用的和开源的。
答案 4 :(得分:7)
Java commons-io有一个FileAlterationObserver。它与FileAlterationMonitor结合进行轮询。类似于公共VFS。优点是它的依赖性要小得多。
编辑:较少的依赖关系不是真的,它们对于VFS是可选的。但它使用java File而不是VFS抽象层。
答案 5 :(得分:3)
“更多NIO功能”具有文件监视功能,其实现取决于底层操作系统。应该在JDK7中。
答案 6 :(得分:3)
每次我去读取属性文件时都会运行这段代码,如果自上次读取文件以来它已被修改,那么实际上只读取该文件。希望这有助于某人。
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
中使用了类似的方法。
答案 7 :(得分:2)
如果你愿意花钱,JNIWrapper是一个有用的Winpack库,你将能够获得某些文件的文件系统事件。不幸的是只有Windows。
http://www.teamdev.com/jniwrapper/index.jsf
否则,使用本机代码并不总是坏事,尤其是当提供的最佳服务是针对本机事件的轮询机制时。
我注意到java文件系统操作在某些计算机上运行缓慢,如果处理不当,很容易影响应用程序性能。
答案 8 :(得分:2)
您可以使用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();
}
}
答案 9 :(得分:1)
有一个名为JxFileWatcher的文件和文件夹的商业跨桌面库。 它可以从这里下载: http://www.teamdev.com/jxfilewatcher/
答案 10 :(得分:1)
您也可以考虑使用Apache Commons JCI(Java编译器接口)。虽然这个API似乎专注于动态编译类,但它的API中还包含监视文件更改的类。
答案 11 :(得分:1)
Spring Integration为观察目录和文件提供了一个很好的机制:http://static.springsource.org/spring-integration/reference/htmlsingle/#files。很确定它是跨平台的(我在mac,linux和windows上使用它)。
答案 12 :(得分:0)
轮询上次修改的文件属性是一个简单而有效的解决方案。只需定义一个扩展我的 /**
* Before starting background thread Show Progress Bar Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* After completing background task Dismiss the progress dialog
* **/
@SuppressWarnings("deprecation")
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
// Declear Variables
int count;
try {
URL url1 = new URL(url);
URLConnection conection = url1.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url1.openStream(),
8192);
// Output stream
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString() + "/Report.xls");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
Log.d("Downloding"+data,"Count"+count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
@Override
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
@SuppressWarnings("deprecation")
@Override
protected void onPostExecute(String reString) {
// dismiss the dialog after the file was downloaded
super.onPostExecute(null);;
dismissDialog(progress_bar_type);
Log.d("Download","Completed");
Intent intent1=new Intent(DownloadExcle.this,MainActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
}
的类并实现FileChangedWatcher
方法:
onModified()
答案 13 :(得分:0)
与其他答案类似,这里我是如何使用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);
}
}
}