Me gustaría recibir una notificación cuando se modifique un archivo en el sistema de archivos. No he encontrado nada más que un hilo que sondea la propiedad lastModified File y claramente esta solución no es óptima.
Gracias por todas las respuestas. Dado que mis necesidades son pequeñas (solo necesito volver a cargar un archivo de propiedades cambiado en mi aplicación web ... principalmente porque reiniciar toda la aplicación web es algo lento), me quedaré con el modelo de encuesta. Al menos ahora sé que no existe una solución sencilla para estos casos.
cheng81
14
Solo una nota. Cuando resolvimos este problema antes, descubrimos que los archivos grandes tienden a llegar lentamente, y el mecanismo de sondeo a menudo descubrió un archivo nuevo o modificado antes de que se escribiera por completo. Para resolver esto, se adoptó una solución de "dos bocados". El encuestador notó que un archivo había cambiado, pero no notificó al sistema de un archivo nuevo / cambiado hasta que se veía igual para dos encuestas: es decir, se había estabilizado. Se corrigieron muchos errores de archivos malos.
Steve Powell
1
Además, Tomcat sufre ese problema al colocar archivos WAR grandes en la carpeta webapps desde fuentes remotas y lo ha hecho durante mucho tiempo.
John Rix
Respuestas:
21
En el nivel bajo, la única forma de modelar esta utilidad es tener un sondeo de subprocesos en un directorio y vigilar los atributos del archivo. Pero puede utilizar patrones para desarrollar un adaptador para dicha utilidad.
Por ejemplo, los servidores de aplicaciones j2ee como Tomcat y otros tienen una función de carga automática en la que tan pronto como cambia el descriptor de implementación o cambia la clase de servlet, la aplicación se reinicia.
Puede usar las bibliotecas de dichos servidores, ya que la mayor parte del código de tomcat es reutilizable y de código abierto.
Esto ya no es cierto en Java 7: ahora hay una API para esto que puede conectarse a los servicios de notificación del sistema operativo: blogs.oracle.com/thejavatutorials/entry/…
Arnout Engelen
Esa API es muy inadecuada, no proporciona notificaciones para eventos de cierre de archivos en Linux. Entonces, dado un caso simple, cuando se cierra un archivo, copiarlo a otro directorio no funciona.
binarytemple_picsolve
117
Escribí un monitor de archivo de registro antes y descubrí que el impacto en el rendimiento del sistema de sondear los atributos de un solo archivo, unas pocas veces por segundo, es en realidad muy pequeño.
Veo los ejemplos como un directorio de observación, pero ¿qué pasa con un archivo individual?
Archimedes Trajano
@ArchimedesTrajano La API le notifica cuando un archivo en un directorio ha cambiado. El evento que se activa incluye el nombre del archivo que ha cambiado. Por lo tanto, puede manejar eventos para un archivo o archivos determinados e ignorar otros.
Existe una biblioteca llamada jnotify que incluye inotify en Linux y también tiene soporte para Windows. Nunca lo usé y no sé qué tan bueno es, pero diría que vale la pena intentarlo.
Funciona perfectamente y es muy sencillo de usar. He estado usando inotify durante muchos años. Es rápido, estable y confiable
2013
8
Java commons-io tiene un FileAlterationObserver . realiza encuestas en combinación con un FileAlterationMonitor. Similar a commons VFS. La ventaja es que tiene muchas menos dependencias.
editar: Menos dependencias no es cierto, son opcionales para VFS. Pero usa Java File en lugar de la capa de abstracción VFS.
¿Podría ser más específico o publicar un enlace a la documentación? Parece que no puedo encontrar nada en esto ...
Luciano
Parece ser el paquete java.nio.file. Vea un tutorial .
David L.
4
Ejecuto este fragmento de código cada vez que voy a leer el archivo de propiedades, y solo leo realmente el archivo si se ha modificado desde la última vez que lo leí. Espero que esto ayude a alguien.
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;}
En Log4J se utiliza un enfoque similar FileWatchdog.
Si está dispuesto a desprenderse de algo de dinero, JNIWrapper es una biblioteca útil con un Winpack, podrá obtener eventos del sistema de archivos en ciertos archivos. Desafortunadamente solo windows.
De lo contrario, recurrir al código nativo no siempre es malo, especialmente cuando lo mejor que se ofrece es un mecanismo de sondeo frente a un evento nativo.
He notado que las operaciones del sistema de archivos de Java pueden ser lentas en algunas computadoras y pueden afectar fácilmente el rendimiento de la aplicación si no se manejan bien.
También puede considerar Apache Commons JCI (Interfaz del compilador de Java). Aunque esta API parece estar enfocada en la compilación dinámica de clases, también incluye clases en su API que monitorean los cambios de archivos.
Existe una biblioteca comercial entre escritorios para la visualización de archivos y carpetas llamada JxFileWatcher. Se puede descargar desde aquí:
http://www.teamdev.com/jxfilewatcher/
Sin embargo, sondear la última propiedad del archivo modificado es una solución simple pero efectiva. Simplemente defina una clase que extienda my FileChangedWatchere implemente el onModified()método:
De manera similar a las otras respuestas, así es como lo hice usando File, Timer y TimerTask para permitir que esto se ejecute como un sondeo de subprocesos en segundo plano a intervalos establecidos.
Respuestas:
En el nivel bajo, la única forma de modelar esta utilidad es tener un sondeo de subprocesos en un directorio y vigilar los atributos del archivo. Pero puede utilizar patrones para desarrollar un adaptador para dicha utilidad.
Por ejemplo, los servidores de aplicaciones j2ee como Tomcat y otros tienen una función de carga automática en la que tan pronto como cambia el descriptor de implementación o cambia la clase de servlet, la aplicación se reinicia.
Puede usar las bibliotecas de dichos servidores, ya que la mayor parte del código de tomcat es reutilizable y de código abierto.
fuente
Escribí un monitor de archivo de registro antes y descubrí que el impacto en el rendimiento del sistema de sondear los atributos de un solo archivo, unas pocas veces por segundo, es en realidad muy pequeño.
Java 7, como parte de NIO.2, ha agregado la API WatchService
fuente
Yo uso la API VFS de Apache Commons, aquí hay un ejemplo de cómo monitorear un archivo sin mucho impacto en el rendimiento:
DefaultFileMonitor
fuente
Existe una biblioteca llamada jnotify que incluye inotify en Linux y también tiene soporte para Windows. Nunca lo usé y no sé qué tan bueno es, pero diría que vale la pena intentarlo.
fuente
Java commons-io tiene un FileAlterationObserver . realiza encuestas en combinación con un FileAlterationMonitor. Similar a commons VFS. La ventaja es que tiene muchas menos dependencias.
editar: Menos dependencias no es cierto, son opcionales para VFS. Pero usa Java File en lugar de la capa de abstracción VFS.
fuente
"Más funciones de NIO" tiene la función de vigilancia de archivos, cuya implementación depende del SO subyacente. Debería estar en JDK7.
fuente
java.nio.file
. Vea un tutorial .Ejecuto este fragmento de código cada vez que voy a leer el archivo de propiedades, y solo leo realmente el archivo si se ha modificado desde la última vez que lo leí. Espero que esto ayude a alguien.
En Log4J se utiliza un enfoque similar
FileWatchdog
.fuente
Puede escuchar los cambios de archivos utilizando un FileReader. Por favor, vea el ejemplo a continuación
fuente
Si está dispuesto a desprenderse de algo de dinero, JNIWrapper es una biblioteca útil con un Winpack, podrá obtener eventos del sistema de archivos en ciertos archivos. Desafortunadamente solo windows.
Consulte https://www.teamdev.com/jniwrapper .
De lo contrario, recurrir al código nativo no siempre es malo, especialmente cuando lo mejor que se ofrece es un mecanismo de sondeo frente a un evento nativo.
He notado que las operaciones del sistema de archivos de Java pueden ser lentas en algunas computadoras y pueden afectar fácilmente el rendimiento de la aplicación si no se manejan bien.
fuente
También puede considerar Apache Commons JCI (Interfaz del compilador de Java). Aunque esta API parece estar enfocada en la compilación dinámica de clases, también incluye clases en su API que monitorean los cambios de archivos.
Ejemplo: http://commons.apache.org/jci/usage.html
fuente
Spring Integration proporciona un buen mecanismo para ver directorios y archivos: http://static.springsource.org/spring-integration/reference/htmlsingle/#files . Estoy bastante seguro de que es multiplataforma (lo he usado en mac, linux y windows).
fuente
Existe una biblioteca comercial entre escritorios para la visualización de archivos y carpetas llamada JxFileWatcher. Se puede descargar desde aquí: http://www.teamdev.com/jxfilewatcher/
También puede verlo en acción en línea: http://www.teamdev.com/jxfilewatcher/onlinedemo/
fuente
Sin embargo, sondear la última propiedad del archivo modificado es una solución simple pero efectiva. Simplemente defina una clase que extienda my
FileChangedWatcher
e implemente elonModified()
método:fuente
De manera similar a las otras respuestas, así es como lo hice usando File, Timer y TimerTask para permitir que esto se ejecute como un sondeo de subprocesos en segundo plano a intervalos establecidos.
fuente