Me gustaría recibir una notificación cuando se haya cambiado un archivo en el sistema de archivos. No he encontrado más que un hilo que sondea la última propiedad del archivo modificado y, evidentemente, esta solución no es óptima.Escucha modificada de archivo en Java
Respuesta
En el nivel bajo, la única forma de modelar esta utilidad es realizar un sondeo de hilos en un directorio y controlar los atributos del archivo. Pero puede usar patrones para desarrollar un adaptador para tal utilidad.
Por ejemplo, los servidores de aplicaciones j2ee como Tomcat y otros tienen una característica de carga automática en la que tan pronto como el descriptor de implementación cambia o la clase de servlet cambia, la aplicación se reinicia.
Puede usar las bibliotecas de dichos servidores ya que la mayoría 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 se puede conectar a los servicios de notificación del sistema operativo: http://blogs.oracle.com/thejavatutorials/entry/watching_a_directory_for_changes –
Esa API es muy inadecuada, no lo hace proporcionar 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. –
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 ventanas.
http://www.teamdev.com/jniwrapper/index.jsf
De lo contrario, recurrir a código nativo no siempre es algo malo sobre todo cuando la mejor oferta es un mecanismo de sondeo, frente a un evento nativo .
He notado que las operaciones del sistema de archivos java pueden ser lentas en algunas computadoras y pueden afectar fácilmente el rendimiento de las aplicaciones si no se manejan bien.
Hay una lib llamada jnotify que envuelve inotify en Linux y también tiene soporte para Windows. Nunca lo usé y no sé lo bueno que es, pero vale la pena intentarlo, diría yo.
Funciona perfectamente y es súper fácil de usar. He estado usando inotify por muchos años. Es rápido, estable y confiable –
He escrito un monitor de archivo de registro antes, y encontré que el impacto en el rendimiento del sistema al sondear los atributos de un único archivo, algunas veces por segundo, es realmente muy pequeño.
Java 7, como parte de NIO.2 ha añadido la API WatchService API
El WatchService está diseñado para aplicaciones que necesitan ser notificado sobre los eventos de cambio de archivo.
veo los ejemplos como un directorio de observación, pero ¿qué pasa con un archivo individual? –
@ArchimedesTrajano La API le notifica cuando un archivo en un directorio ha cambiado. El evento que se desencadena incluye el nombre del archivo que ha cambiado. De modo que puede manejar eventos para un cierto archivo o archivos e ignorar otros. – Michael
@ArchimedesTrajano https://stackoverflow.com/questions/16251273/can-i-watch-for-single-file-change-with-watchservice-not-the-whole-directory – user1742529
"Más funciones de NIO" tiene funcionalidad de vigilancia de archivos, con implementación dependiente del sistema operativo subyacente. Debería estar en JDK7.
¿Podría ser más específico o publicar un enlace? a la documentación? Parece que no puede encontrar nada en este ... – Luciano
que utilizan la API VFS de Apache Commons, aquí es un ejemplo de cómo controlar un archivo sin mucho impacto en el rendimiento:
gracias por esta respuesta!exactamente lo que busqué ... –
muy útil, gracias –
Hay una biblioteca multiescritorio comercial para archivos y carpetas mirando llamado JxFileWatcher. Se puede descargar desde aquí: http://www.teamdev.com/jxfilewatcher/
también se puede ver en acción en línea: http://www.teamdev.com/jxfilewatcher/onlinedemo/
También puede considerar el Apache Commons JCI (Java Compiler Interface). Aunque esta API parece centrarse en la compilación dinámica de clases, también incluye clases en su API que supervisa los cambios de archivos.
Integración Spring proporciona un buen mecanismo para la observación de 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).
Ejecuto este fragmento de código cada vez que voy a leer el archivo de propiedades, solo leyendo realmente el archivo si se ha modificado desde la última vez que lo leí. Espero que esto ayude a alguien.
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;
}
Similar approach se utiliza en Log4J FileWatchdog
.
Java commons-io tiene un FileAlterationObserver. realiza sondeos en combinación con un FileAlterationMonitor. Similar a los VFS comunes. La ventaja es que tiene muchas menos dependencias.
editar: Menos dependencias no son ciertas, son opcionales para VFS. Pero usa el archivo java en lugar de la capa de abstracción VFS.
Puede escuchar los cambios de archivos usando un FileReader. Por favor vea el ejemplo a continuació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();
}
}
Sin embargo, la votación de la última propiedad del archivo modificado es una solución simple pero efectiva. Sólo definir una clase que se extiende mi FileChangedWatcher
e implementar el onModified()
método:
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();
}
Al igual que en las otras respuestas, aquí está cómo lo hice usando Archivo, Temporizador y TimerTask para que esta carrera como un sondeo subproceso en segundo plano a intervalos fijos .
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);
}
}
}
- 1. Evento de orientación modificada o Escucha
- 2. Java - Escucha cambio de variable
- 3. Eliminar archivo de la confirmación modificada
- 4. fecha/hora modificada con formato de archivo en mac bash?
- 5. Java DatagramSocket escucha en una dirección de difusión
- 6. Toque un archivo - actualice su marca de tiempo modificada
- 7. Advertencia: modificada en el futuro
- 8. Escucha de directorio en C#
- 9. Orden modificada en main.xml, ahora obtengo ClassCastException
- 10. Fecha de acceso del archivo no modificada después de leer el archivo por [NSData dataWithContentsOfURL: ...]
- 11. Cómo agregar escucha de acción que escucha varios botones
- 12. estado de escucha WIFI
- 13. Java: ¿Archivo a maleficio?
- 14. Escucha de cambio de valor en JTextField
- 15. Backbone.js parse respuesta no modificada
- 16. ¿Escucha de cambio de volumen?
- 17. ¿Escucha eventos de historia en Firefox?
- 18. ¿Cómo obtengo la fecha/hora modificada de un archivo en Python?
- 19. C#: Oído de escucha UDP
- 20. archivo sqlite3 agregar en .gitignore pero aún está en la lista modificada?
- 21. Eficiencia de while (true) ServerSocket Escucha
- 22. Evento de selección modificada utilizando MVVM
- 23. ¿Escucha de eventos en Java sin aplicación con foco? (Detección global de pulsaciones de teclas)
- 24. Escucha teclado USB con Python
- 25. Manera correcta de manipular 304 no modificada en jQuery ajax
- 26. problema redirigir la salida de depuración en un archivo mediante escucha de seguimiento
- 27. WPF actualización de fuente de DataGrid en la celda modificada
- 28. Visualización de vista previa de cámara en vivo modificada
- 29. ¿cómo puedo establecer la última hora modificada de un archivo de python?
- 30. poniendo escucha "On Change" en jFormattedTextField
Gracias por todas las respuestas. Como mis necesidades son pequeñas (solo tengo que volver a cargar un archivo de propiedad en mi aplicación web modificada ... principalmente porque reiniciar toda la aplicación web es un poco lento), me mantendré firme con el modelo de encuesta. Al menos ahora sé que no hay una solución simple para estos casos. – cheng81
Solo una nota. Cuando resolvimos este problema, descubrimos que los archivos grandes tienden a entrar lentamente, y el mecanismo de sondeo a menudo descubría un archivo nuevo o modificado antes de que se escribiera por completo. Para resolver esto, se adoptó una solución de "dos mordiscos". El encuestador notó que un archivo había cambiado, pero no notificó al sistema sobre un archivo nuevo/modificado hasta que parecía el mismo para dos encuestas: es decir, se había estabilizado. Curado una gran cantidad de errores de archivo incorrecto. –
Como un lado, Tomcat sufre ese problema al colocar grandes archivos WAR en la carpeta webapps desde fuentes remotas y lo ha hecho durante mucho tiempo. –