Arquivo alterado ouvinte em Java
Pergunta
Eu gostaria de ser notificado quando um arquivo foi alterado no sistema de arquivos. Eu não encontrei nada, mas um segmento que controla a propriedade de arquivo lastModified e claramente esta solução não é ideal.
Solução
Ao nível baixo a única maneira de modelar esta utilidade é ter um polling linha em um diretório e manter uma vigilância sobre os atributos do arquivo. Mas você pode usar padrões para desenvolver um adaptador para esse utilitário a.
Para servidores de aplicativos exemplo J2EE como Tomcat e outros têm uma característica de carga automático, onde, na maior brevidade mudanças descritor de implementação ou classe servlet muda o aplicativo for reiniciado.
Você pode usar as bibliotecas de tais servidores, como a maioria do código de tomcat é reutilizável e opensource.
Outras dicas
Eu escrevi um monitor de arquivo de log antes, e eu achei que o impacto no desempenho do sistema de votação os atributos de um único arquivo, algumas vezes por segundo, é realmente muito pequeno.
Java 7, como parte de NIO.2 acrescentou o WatchService API
A API WatchService é projetado para aplicações que precisam ser notificados sobre os eventos de alteração de arquivo.
Eu uso a API VFS do Apache Commons, aqui está um exemplo de como monitorar um arquivo sem muito impacto no desempenho:
commons-io Java tem um FileAlterationObserver . ele faz sondagens em combinação com um FileAlterationMonitor. Semelhante ao Commons VFS. O advantag é que ele tem muito menos dependências.
edit: Menos dependências não é verdade, eles são opcionais para VFS. Mas ele usa java arquivo em vez da camada de abstração de VFS.
"Mais NIO apresenta" tem a funcionalidade de relógio de arquivo, com a implementação depende do sistema operacional subjacente. Deve estar em JDK7.
Eu corro esse trecho de código cada vez que vou para ler o arquivo de propriedades, única realmente ler o arquivo se ele foi modificado desde a última vez que eu li. Espero que isso ajude alguém.
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;
}
abordagem semelhante é usado em Log4J FileWatchdog
.
Você pode ouvir as alterações de arquivos usando um FileReader. Plz veja o exemplo abaixo
// 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();
}
}
Se você estiver disposto a parte com algum dinheiro, JNIWrapper é uma biblioteca útil com um Winpack, você será capaz de obter eventos do sistema de arquivos em certos arquivos. Infelizmente, somente para Windows.
Consulte https://www.teamdev.com/jniwrapper .
Caso contrário, recorrendo a código nativo não é sempre uma coisa ruim, especialmente quando o melhor em oferta é um mecanismo de pesquisa, como a um evento nativo.
Eu tenho notado que as operações do sistema de arquivos Java pode ser lento em alguns computadores e pode facilmente afetar o desempenho do aplicativo se não for bem tratada.
Você também pode considerar o Apache Commons JCI (Java Compiler Interface). Embora esta API parece estar focada na compilação dinâmica das aulas, ele também inclui aulas em sua API que mudanças de arquivos monitores.
Spring Integration fornece um mecanismo legal para assistir diretórios e arquivos: http: / /static.springsource.org/spring-integration/reference/htmlsingle/#files . Certeza que é multiplataforma (Eu usei-o no mac, linux e windows).
Há uma biblioteca multi-desktop comercial para arquivos e pastas assistindo chamado JxFileWatcher. Ele pode ser baixado a partir daqui: http://www.teamdev.com/jxfilewatcher/
Além disso, você pode vê-lo em ação on-line: http://www.teamdev.com/jxfilewatcher/onlinedemo/
Polling a última propriedade arquivo modificado é uma solução eficaz, embora simples ainda. Apenas definir uma classe estender minha FileChangedWatcher
e implementar o método 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();
}
Assim como as outras respostas, aqui está como eu fiz isso usando Arquivo, Timer, e TimerTask para deixar esta corrida como um polling discussão de fundo em intervalos definidos.
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);
}
}
}