質問
私は、ファイルがファイルシステムに変更されたときに通知されるようにしたいと思います。私は世論調査LASTMODIFIEDファイルのプロパティと明確に、このソリューションが最適でないスレッドしか認められません。
解決
低レベルでは、このユーティリティをモデル化する唯一の方法は、ディレクトリ上のスレッドのポーリングを持つことで、ファイルの属性に時計を維持します。しかし、あなたは、このようなユーティリティ用のアダプタを開発するためにパターンを使用することができます。
例えばTomcatおよび他のようなJ2EEアプリケーションサーバーが自動ロード機能を持っているには、すぐに、デプロイメント・ディスクリプタの変更やサーブレットクラスなどのアプリケーションの再起動を変更するところます。
Tomcatののコードのほとんどが再利用可能とオープンソースであるとしてあなたは、このようなサーバからのライブラリを使用することができます。
他のヒント
私は、ログファイルのモニターの前に書いた、と私は、ポーリングのシステムのパフォーマンスへの影響は単一のファイルの属性、数回秒を、実際には非常に小さいことがわかっています。
NIO.2の一部としてのJava 7は、 WatchService APIを追加しましたの
WatchServiceのAPIは、ファイル変更イベントについて通知する必要があるアプリケーション向けに設計されています。
私は、Apache CommonsのからVFSのAPIを使用し、ここでのパフォーマンスにあまり影響を与えずにファイルを監視する方法の例です。
<のhref = "http://commons.apache.org/proper/commons-vfs/commons-vfs2/apidocs/org/apache/commons/vfs2/impl/DefaultFileMonitor.html" のrel = "nofollowをnoreferrer" > DefaultFileMonitor の
<のhref = "HTTPをラップ jnotify に呼ばれるlibにあります。 ORG /ウィキ/バージョンinotify」のrel = "noreferrer"> inotifyをのLinux上でもウィンドウをサポートしています。それを使ったことがないと私はそれがどのように良いかわからないが、それは私が言うと思い試してみる価値はあります。
のJavaコモンズ-ioが<のhref = "http://commons.apache.org/proper/commons-io//javadocs/api-release/org/apache/commons/io/monitor/FileAlterationObserver.htmlを持っています「> FileAlterationObserver を。それはFileAlterationMonitorとの組み合わせでポーリングを行います。コモンズVFSに似ています。 advantagはそれがはるかに少ないの依存関係を持っているということです。
編集:あまり依存関係が事実ではない、彼らはVFSのためのオプションです。しかし、それはJavaファイルの代わりに、VFS抽象化レイヤーを使用します。
「もっとNIOの機能は、」基盤となるOSに依存して実装して、ファイルの時計機能を備えています。 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();
}
}
は、特定のファイル上のファイルシステムイベントを取得することができます。残念ながら、Windowsのみます。
を参照してください。 https://www.teamdev.com/jniwrapperするます。
それ以外の場合は、ネイティブコードに頼ることは提供する上で最高のネイティブイベントに対するとしてポーリング機構である場合は特に、常に悪いことではありません。
私は、Javaファイルシステム操作が一部のコンピュータ上で遅くなることが、よく処理されない場合は簡単にアプリケーションのパフォーマンスに影響を与える可能性があることに気付きました。
また、ApacheのコモンズJCI(JavaコンパイラInterface)を検討することができます。このAPIは、クラスの動的コンパイルに焦点を当てているようだが、それはまた、ファイルの変更を監視し、そのAPIのクラスが含まれます。
春の統合は、ディレクトリとファイルを見るために素敵なメカニズムを提供します/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);
}
}
}