qué que manejador interfaz eventos evento escuchar adaptador java file listener

que - Archivo cambiado oyente en Java



que es un evento en java (14)

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.


"Más funciones de NIO" tiene funcionalidad de vigilancia de archivos, y la implementación depende del sistema operativo subyacente. Debería estar en JDK7.


De forma 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 hilos de fondo en intervalos establecidos.

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); } } }


Ejecuto este fragmento de código cada vez que voy a leer el archivo de propiedades, solo leyendo 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; }

Un enfoque similar se utiliza en Log4J FileWatchdog .


En el nivel bajo, la única forma de modelar esta utilidad es realizar un sondeo de hilos en un directorio y observar 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 función 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.



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.


He escrito un monitor de archivos de registro antes, y descubrí que el impacto en el rendimiento del sistema al sondear los atributos de un solo archivo, algunas veces por segundo, es realmente muy pequeño.

Java 7, como parte de NIO.2 ha agregado la API WatchService

La API WatchService está diseñada para aplicaciones que necesitan ser notificadas sobre eventos de cambio de archivos.


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 es cierto, 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(); } }


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 al código nativo no siempre es algo malo, especialmente cuando lo mejor que se ofrece es un mecanismo de sondeo en comparación con un evento nativo.

Me di cuenta de 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.


Sin embargo, sondear la última propiedad del archivo modificado es una solución simple pero efectiva. Solo defina una clase que FileChangedWatcher mi FileChangedWatcher e implemente el 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(); }



También puede considerar la Apache Commons JCI (Interfaz del compilador de Java). 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.

Ejemplo: http://commons.apache.org/jci/usage.html


Uso la API de VFS de Apache Commons, aquí hay un ejemplo de cómo monitorear un archivo sin mucho impacto en el rendimiento:

DefaultFileMonitor