Dosya sisteminde bir dosya değiştirildiğinde bilgilendirilmek istiyorum. LastModified File özelliğini sorgulayan bir iş parçacığından başka bir şey bulamadım ve açıkça bu çözüm optimal değil.
Dosya sisteminde bir dosya değiştirildiğinde bilgilendirilmek istiyorum. LastModified File özelliğini sorgulayan bir iş parçacığından başka bir şey bulamadım ve açıkça bu çözüm optimal değil.
Yanıtlar:
Düşük düzeyde, bu yardımcı programı modellemenin tek yolu, bir dizinde bir iş parçacığı sorgulaması yapmak ve dosyanın özniteliklerine bir göz atmaktır. Ancak, böyle bir yardımcı program için bir bağdaştırıcı geliştirmek için desenleri kullanabilirsiniz.
Örneğin, Tomcat ve diğerleri gibi j2ee uygulama sunucuları, dağıtım tanımlayıcısı değişir veya sunucu uygulaması sınıfı değişir değişmez uygulamanın yeniden başlatıldığı otomatik yükleme özelliğine sahiptir.
Tomcat kodunun çoğu yeniden kullanılabilir ve açık kaynaklı olduğu için bu tür sunuculardaki kitaplıkları kullanabilirsiniz.
Daha önce bir günlük dosyası izleyicisi yazdım ve tek bir dosyanın özniteliklerini saniyede birkaç kez yoklamanın sistem performansı üzerindeki etkisinin aslında çok küçük olduğunu gördüm.
Java 7, NIO.2 parçası eklemiştir olarak WatchService API
WatchService API, dosya değişikliği olayları hakkında bilgilendirilmesi gereken uygulamalar için tasarlanmıştır.
Apache Commons'ın VFS API'sini kullanıyorum, işte performansı çok fazla etkilemeden bir dosyanın nasıl izleneceğine dair bir örnek:
Denilen bir lib vardır jnotify sarar olduğunu Inotify linux üzerinde ve aynı zamanda pencere desteği vardır. Hiç kullanmadım ve ne kadar iyi olduğunu bilmiyorum ama denemeye değer diyorum.
Java commons- io'nun bir FileAlterationObserver'ı vardır . FileAlterationMonitor ile birlikte yoklama yapar. Commons VFS'ye benzer. Avantajı, çok daha az bağımlılığa sahip olmasıdır.
düzenleme: Daha az bağımlılık doğru değildir, bunlar VFS için isteğe bağlıdır. Ancak VFS soyutlama katmanı yerine java Dosyası kullanır.
"Daha fazla NIO özelliği", uygulama temeldeki işletim sistemine bağlı olarak dosya izleme işlevine sahiptir. JDK7'de olmalıdır.
Özellikler dosyasını her okumaya gittiğimde bu kod parçacığını çalıştırıyorum, sadece dosyayı son okuduğumdan beri değiştirilmişse gerçekten okuyorum. Umarım bu birine yardımcı olur.
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'de benzer bir yaklaşım kullanılmaktadır FileWatchdog
.
Bir FileReader kullanarak dosya değişikliklerini dinleyebilirsiniz. Plz aşağıdaki örneğe bakın
// 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();
}
}
Biraz parayla ayrılmak istiyorsanız, JNIWrapper bir Winpack ile kullanışlı bir kitaplıktır, belirli dosyalarda dosya sistemi olaylarını alabilirsiniz. Ne yazık ki sadece pencereler.
Bkz https://www.teamdev.com/jniwrapper .
Aksi takdirde, yerel koda başvurmak her zaman kötü bir şey değildir, özellikle sunulan en iyi şey yerel bir olaya karşı bir oylama mekanizması olduğunda.
Java dosya sistemi işlemlerinin bazı bilgisayarlarda yavaş olabileceğini ve iyi işlenmezse uygulamanın performansını kolayca etkileyebileceğini fark ettim.
Apache Commons JCI'yi (Java Derleyici Arayüzü) de düşünebilirsiniz. Bu API, sınıfların dinamik derlenmesine odaklanmış gibi görünse de, API'sinde dosya değişikliklerini izleyen sınıfları da içerir.
Spring Integration, Dizinleri ve dosyaları izlemek için güzel bir mekanizma sağlar: http://static.springsource.org/spring-integration/reference/htmlsingle/#files . Çapraz platform olduğundan oldukça eminim (Mac, linux ve pencerelerde kullandım).
Dosya ve klasörleri izlemek için JxFileWatcher adında ticari bir çapraz masaüstü kitaplığı vardır. Buradan indirilebilir: http://www.teamdev.com/jxfilewatcher/
Ayrıca çevrimiçi olarak eylem halinde görebilirsiniz: http://www.teamdev.com/jxfilewatcher/onlinedemo/
Yine de son değiştirilen dosya özelliğini sorgulamak basit ama etkili bir çözümdür. Sadece my'ı genişleten bir sınıf tanımlayın FileChangedWatcher
ve onModified()
yöntemi uygulayın:
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();
}
Diğer yanıtlara benzer şekilde, File, Timer ve TimerTask kullanarak bunun belirli aralıklarla arka plan iş parçacığı yoklaması olarak çalışmasına izin vermek için bunu nasıl yaptım.
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);
}
}
}