Gostaria de ser notificado quando um arquivo for alterado no sistema de arquivos. Não encontrei nada além de um thread que pesquisa a propriedade lastModified File e, claramente, essa solução não é a ideal.
Obrigado por todas as respostas. Como minhas necessidades são pequenas (só preciso recarregar um arquivo de propriedade alterado no meu aplicativo da web ... principalmente porque reiniciar todo o webapp é meio lento), vou ficar com o modelo de pesquisa. Pelo menos agora sei que não existe uma solução simples para esses casos.
cheng81
14
Apenas uma nota. Quando resolvemos esse problema antes, descobrimos que arquivos grandes tendem a chegar lentamente e o mecanismo de pesquisa frequentemente descobria um arquivo novo ou alterado antes de ser totalmente escrito. Para resolver isso, foi adotada uma solução de 'duas mordidas'. O pesquisador percebeu que um arquivo havia sido alterado, mas não notificou o sistema sobre um arquivo novo / alterado até que parecesse o mesmo para duas pesquisas: isto é, estabilizou. Curou muitos erros de badfile.
Steve Powell
1
Como um aparte, o Tomcat sofre esse problema ao soltar grandes arquivos WAR na pasta webapps de fontes remotas e tem feito isso por um longo tempo.
John Rix
Respostas:
21
No nível mais baixo, a única maneira de modelar esse utilitário é ter uma pesquisa de encadeamento em um diretório e observar os atributos do arquivo. Mas você pode usar padrões para desenvolver um adaptador para esse utilitário.
Por exemplo, servidores de aplicativos j2ee, como Tomcat e outros, têm um recurso de carregamento automático em que, assim que o descritor de implementação muda ou a classe de servlet muda, o aplicativo é reiniciado.
Você pode usar as bibliotecas de servidores como a maioria do código do tomcat é reutilizável e de código aberto.
Isso não é mais verdade no Java 7: agora há uma API para isso que pode se conectar aos serviços de notificação do sistema operacional: blogs.oracle.com/thejavatutorials/entry/…
Arnout Engelen
Essa API é altamente inadequada, ela não fornece notificação para eventos de fechamento de arquivo no Linux. Portanto, em um caso simples, quando um arquivo é fechado, copiá-lo para outro diretório não funciona.
binarytemple_picsolve
117
Já escrevi um monitor de arquivo de log antes e descobri que o impacto sobre o desempenho do sistema de pesquisar os atributos de um único arquivo, algumas vezes por segundo, é realmente muito pequeno.
vejo os exemplos como diretório de observação, mas e um arquivo individual?
Archimedes Trajano
@ArchimedesTrajano A API avisa quando um arquivo em um diretório é alterado. O evento acionado inclui o nome do arquivo que foi alterado. Assim, você pode manipular eventos para um determinado arquivo ou arquivos e ignorar outros.
Existe uma biblioteca chamada jnotify que envolve o inotify no linux e também tem suporte para windows. Nunca usei e não sei o quão bom é, mas vale a pena tentar eu diria.
Funciona perfeitamente e é super simples de usar. Eu uso o inotify há muitos anos. É rápido, estável e confiável
oᴉɹǝɥɔ
8
Java commons-io tem um FileAlterationObserver . ele faz polling em combinação com um FileAlterationMonitor. Semelhante ao VFS comum. A vantagem é que ele tem muito menos dependências.
editar: Menos dependências não é verdade, são opcionais para VFS. Mas ele usa o arquivo java em vez da camada de abstração VFS.
Você poderia ser mais específico ou postar um link para a documentação? Não consigo encontrar nada sobre isso ...
Luciano
Parece ser o pacote java.nio.file. Veja um tutorial .
David L.
4
Eu executo esse trecho de código toda vez que vou ler o arquivo de propriedades, apenas lendo o arquivo se ele foi modificado desde a última vez que o li. Espero que isso ajude alguém.
privatelong timeStamp;privateFile file;privateboolean isFileUpdated(File file ){this.file = file;this.timeStamp = file.lastModified();if(this.timeStamp != timeStamp ){this.timeStamp = timeStamp;//Yes, file is updatedreturntrue;}//No, file is not updatedreturnfalse;}
Abordagem semelhante é usada no Log4J FileWatchdog.
Se você está disposto a gastar algum dinheiro, JNIWrapper é uma biblioteca útil com um Winpack, você poderá obter eventos do sistema de arquivos em certos arquivos. Infelizmente, apenas o Windows.
Caso contrário, recorrer ao código nativo nem sempre é uma coisa ruim, especialmente quando o melhor em oferta é um mecanismo de votação em oposição a um evento nativo.
Percebi que as operações do sistema de arquivos Java podem ser lentas em alguns computadores e podem facilmente afetar o desempenho do aplicativo se não forem bem gerenciadas.
Você também pode considerar o Apache Commons JCI (Java Compiler Interface). Embora essa API pareça estar focada na compilação dinâmica de classes, ela também inclui classes em sua API que monitora as alterações de arquivo.
Há uma biblioteca comercial entre desktops para monitoramento de arquivos e pastas chamada JxFileWatcher. Ele pode ser baixado aqui:
http://www.teamdev.com/jxfilewatcher/
No entanto, pesquisar a última propriedade do arquivo modificado é uma solução simples, mas eficaz. Basta definir uma classe estendendo my FileChangedWatchere implementar o onModified()método:
Semelhante às outras respostas, aqui está como fiz isso usando File, Timer e TimerTask para permitir que isso seja executado como uma pesquisa de thread em segundo plano em intervalos definidos.
Respostas:
No nível mais baixo, a única maneira de modelar esse utilitário é ter uma pesquisa de encadeamento em um diretório e observar os atributos do arquivo. Mas você pode usar padrões para desenvolver um adaptador para esse utilitário.
Por exemplo, servidores de aplicativos j2ee, como Tomcat e outros, têm um recurso de carregamento automático em que, assim que o descritor de implementação muda ou a classe de servlet muda, o aplicativo é reiniciado.
Você pode usar as bibliotecas de servidores como a maioria do código do tomcat é reutilizável e de código aberto.
fonte
Já escrevi um monitor de arquivo de log antes e descobri que o impacto sobre o desempenho do sistema de pesquisar os atributos de um único arquivo, algumas vezes por segundo, é realmente muito pequeno.
Java 7, como parte do NIO.2, adicionou a API WatchService
fonte
Eu uso a API VFS do Apache Commons, aqui está um exemplo de como monitorar um arquivo sem muito impacto no desempenho:
DefaultFileMonitor
fonte
Existe uma biblioteca chamada jnotify que envolve o inotify no linux e também tem suporte para windows. Nunca usei e não sei o quão bom é, mas vale a pena tentar eu diria.
fonte
Java commons-io tem um FileAlterationObserver . ele faz polling em combinação com um FileAlterationMonitor. Semelhante ao VFS comum. A vantagem é que ele tem muito menos dependências.
editar: Menos dependências não é verdade, são opcionais para VFS. Mas ele usa o arquivo java em vez da camada de abstração VFS.
fonte
"Mais recursos NIO" tem funcionalidade de observação de arquivo, com implementação dependente do sistema operacional subjacente. Deve estar em JDK7.
fonte
java.nio.file
. Veja um tutorial .Eu executo esse trecho de código toda vez que vou ler o arquivo de propriedades, apenas lendo o arquivo se ele foi modificado desde a última vez que o li. Espero que isso ajude alguém.
Abordagem semelhante é usada no Log4J
FileWatchdog
.fonte
Você pode ouvir as alterações do arquivo usando um FileReader. Por favor, veja o exemplo abaixo
fonte
Se você está disposto a gastar algum dinheiro, JNIWrapper é uma biblioteca útil com um Winpack, você poderá obter eventos do sistema de arquivos em certos arquivos. Infelizmente, apenas o Windows.
Veja https://www.teamdev.com/jniwrapper .
Caso contrário, recorrer ao código nativo nem sempre é uma coisa ruim, especialmente quando o melhor em oferta é um mecanismo de votação em oposição a um evento nativo.
Percebi que as operações do sistema de arquivos Java podem ser lentas em alguns computadores e podem facilmente afetar o desempenho do aplicativo se não forem bem gerenciadas.
fonte
Você também pode considerar o Apache Commons JCI (Java Compiler Interface). Embora essa API pareça estar focada na compilação dinâmica de classes, ela também inclui classes em sua API que monitora as alterações de arquivo.
Exemplo: http://commons.apache.org/jci/usage.html
fonte
O Spring Integration fornece um bom mecanismo para monitorar diretórios e arquivos: http://static.springsource.org/spring-integration/reference/htmlsingle/#files . Tenho certeza que é plataforma cruzada (eu usei no mac, linux e windows).
fonte
Há uma biblioteca comercial entre desktops para monitoramento de arquivos e pastas chamada JxFileWatcher. Ele pode ser baixado aqui: http://www.teamdev.com/jxfilewatcher/
Também você pode vê-lo em ação online: http://www.teamdev.com/jxfilewatcher/onlinedemo/
fonte
No entanto, pesquisar a última propriedade do arquivo modificado é uma solução simples, mas eficaz. Basta definir uma classe estendendo my
FileChangedWatcher
e implementar oonModified()
método:fonte
Semelhante às outras respostas, aqui está como fiz isso usando File, Timer e TimerTask para permitir que isso seja executado como uma pesquisa de thread em segundo plano em intervalos definidos.
fonte