WatchService no sondeo correctamente

Miguel :

Me gustaría sondear un directorio cada 10 segundos para ver si los archivos se han añadido o modificado. Si su son cualquier cambio dentro de los 10 segundos me gustaría tener un conjunto de todas las rutas de archivos que después puedo pasar a otro método.

Problema

Cuando se agrega un archivo que se reconoce inmediatamente y el addedFilesmétodo se llama. En su lugar estaría esperando a esperar 10 segundos y llamar al addedFilesmétodo con múltiples archivos que se han encontrado.

Ejemplo
He creado un ejemplo completo que vigila un directorio. Un hilo luego espera 5 segundos y copias 2000 archivos en el directorio visto.
El comportamiento esperado es que el WatchServicepara comprobar si hay cambios cada 10 segundos. En su lugar, parece estar recogiendo los cambios al instante.

Código

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;

public class DirectoryWatcherExample 
{
    private static final int POLLING_TIME = 10;

    public static void main(final String args[]) throws InterruptedException, IOException
    {
        final Path directory = Paths.get("directory/to/be/watched");

        /**
         * Start a thread that will create 2000 files to the selected directory
         * This will occur after waiting 5 seconds.
         */
        new Thread(new Runnable()
        {
            @Override
            public void run() 
            {
                try 
                {
                    Thread.sleep(5000);         
                    System.out.println("Copying 2000 files to directory: " + directory);
                    for(int i = 0; i < 2000; i++)
                    {
                        final PrintWriter writer = new PrintWriter(directory.resolve("test_file_" + i + ".txt").toFile(), "UTF-8");
                        writer.println("The first line");
                        writer.println("The second line");
                        writer.close();
                    }
                    System.out.println("Finished copying files to directory: " + directory);
                } 
                catch (final Exception e) 
                {
                    e.printStackTrace();
                } 
            }
        }).start();

        /**
         * Start the watch service polling every 10 seconds
         */
        new DirectoryWatcherExample().startWatchService(directory);
    }

    public void startWatchService(final Path directory) throws InterruptedException, IOException
    {
        final WatchService watchService = FileSystems.getDefault().newWatchService();
        directory.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);

        while(true)
        {
            System.out.println("Start polling");
            final WatchKey key = watchService.poll(POLLING_TIME, TimeUnit.SECONDS);
            System.out.println("Finished polling and retrieved key");

            if(key != null)
            {
                final Collection<Path> paths = new HashSet<>();
                for (final WatchEvent<?> watchEvent : key.pollEvents())
                {
                    final Path path = ((Path) key.watchable()).resolve((Path) watchEvent.context());
                    paths.add(path);
                    System.out.println("Path added: " + path);
                }

                // Do something with the paths
                addedFiles(paths);

                if (!key.reset())
                {
                    break;
                }   
            }

        }
    }

    // Unimplemented
    public void addedFiles(final Collection<Path> paths)
    {

    }
}

Lo que podría ser la causa de esto?

Saptarshi Basu:

Hay dos opciones:

  1. Es necesario invocar pollen el watchServicedespués de un cierto intervalo por dormir en el medio. Como otros señalaron, el tiempo de espera en el pollmétodo es para escenarios en los que no hay ningún evento en el búfer. También, ya que no está manejando los acontecimientos inmediatamente, algunos de los acontecimientos puede desbordar el buffer de sistema operativo y con el tiempo perdido. Por lo tanto, es necesario controlar el escenario desbordamiento también.

  2. Alternativamente, es posible que desee utilizar la biblioteca de Seguimiento del archivo de Apache Commons IO. Se sondea el sistema de archivos como desee. Incluso puede configurar el intervalo de sondeo.

Se refieren a las tres clases / interfaz siguiendo aquí :

  • FileAlterationMonitor- Se trata básicamente de un hilo (una Runnableaplicación), que tiene capacidad para el intervalo de sondeo y después de cada intervalo invocaFileAlterationObserver
  • FileAlterationObserver- En él se enumeran los archivos en el directorio, compara la lista actual con la lista anterior, identifica los cambios en los archivos e invoca el método adecuado en la FileAlterationListeneraplicación
  • FileAlterationListener - La interfaz que es necesario implementar y escribir la lógica

Lo que usted puede considerar hacer para su caso de uso es, seguir añadiendo todos los detalles de los archivos en una lista como y cuando se agregan o se modifican. Por último, cuando el onStop()se invoca el método, se llama a su addedFilesmétodo con la lista completa, borre la lista y empezar de nuevo.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=206099&siteId=1
Recomendado
Clasificación