3

ENTRY_DELETEENTRY_CREATEおよびENTRY_MODIFYイベントのディレクトリを監視し、イベントに基づいてロジックを実行する監視サービスがあります。

すべての変更についてディレクトリを監視し、ループを終了しないサービスが必要です。しかし、他のロジックも開始する必要があります。

Runnableこれらのメソッドをリファクタリングしてこれを達成するにはどうすればよいですか?

以下、コードの場合。

public static void main(String[] args) {        
    System.out.println("Started watching");
    FileServices fileServices = new FileServicesImpl();

    fileServices.setSrcDir(fileServices.getValue("srcdir","properties/abc.properties"));
    fileServices.setDestDir(fileServices.getValue("destdir","properties/abc.properties"));

    System.out.println(fileServices.getSrcDir());
    System.out.println(fileServices.getDestDir());

    Map<String,WatchEvent> files = new HashMap<>();
    MappingConsole mappingConsole = new MappingConsole();

    for(;;){
        files = fileServices.getEventMap();
        for(String f : files.keySet()){
            System.out.println("Size of files: "+files.size());
            if (files.get(f).kind() == ENTRY_CREATE || files.get(f).kind() == ENTRY_MODIFY) {
                System.out.println("Processing: " +f);
                mappingConsole.map940(fileServices.getSrcDir(),f,fileServices.getDestDir());
                System.out.println("Processed: " +f);
            }
        }
    }

}

FileServicesImpl から:

@Override
public void monitorSrcDir(String srcDir){
    for(;;){
        try {
            WatchService watchService = FileSystems.getDefault().newWatchService();
            Path myDir = Paths.get(srcDir);
            WatchService watcher = myDir.getFileSystem().newWatchService();
            myDir.register(watcher, ENTRY_CREATE,ENTRY_DELETE, ENTRY_MODIFY);
            WatchKey watchKey = watcher.take();
            List<WatchEvent<?>> events = watchKey.pollEvents();
            for (WatchEvent event : events) {
                if (event.kind() == ENTRY_CREATE) {
                    System.out.println("Create: " + event.context().toString());
                    getEventMap().put(event.context().toString(), event);
                }
                if (event.kind() == ENTRY_DELETE) {
                    System.out.println("Delete: " + event.context().toString());
                    getEventMap().put(event.context().toString(), event);
                }
                if (event.kind() == ENTRY_MODIFY) {
                    System.out.println("Modify: " + event.context().toString());
                    getEventMap().put(event.context().toString(), event);
                }
            }
            watchKey.reset();
        }  catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
4

1 に答える 1

1

私はこれをします:

public class WatchServiceMonitor implements Monitor, Runnable, Closeable {
    private static Logger log = LoggerFactory.getLogger( WatchServiceMonitor.class.getName() );
    private Destination destination;
    private Path hotFolder;
    private Thread thread;

    public WatchServiceMonitor( Path hotFolder, Destination destination ) {
        this.hotFolder = hotFolder;
        this.destination = destination;

    }

    @Override
    public void close() throws IOException {
        try {
            stop();
        }
        catch ( InterruptedException e ) {
            log.warn( "request to stop failed, guess its time to stop being polite!" );
        }
    }

    @Override
    public void join() throws InterruptedException {
        thread.join();
    }

    @Override
    public void run() {
        try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
            if ( log.isTraceEnabled() ) log.trace( "registering create watcher on " + hotFolder.toAbsolutePath().toString() );
            hotFolder.register( watcher, StandardWatchEventKinds.ENTRY_CREATE );
            if ( log.isDebugEnabled() ) log.debug( "watcher registration complete for " + hotFolder.toAbsolutePath().toString() );
            synchronized ( this ) {
                this.notifyAll();
            }
            for ( ;; ) {
                if ( thread.isInterrupted() ) break;

                WatchKey key = null;
                try {
                    log.trace( "waiting for create event" );
                    key = watcher.take();
                    log.trace( "got an event, process it" );
                }
                catch ( InterruptedException ie ) {
                    log.trace( "interruped, must be time to shut down..." );
                    break;
                }

                for ( WatchEvent<?> eventUnknown : key.pollEvents() ) {
                    WatchEvent.Kind<?> kind = eventUnknown.kind();

                    if ( kind == StandardWatchEventKinds.OVERFLOW ) return;

                    @SuppressWarnings( "unchecked" )
                    WatchEvent<Path> eventPath = (WatchEvent<Path>) eventUnknown;
                    Path path = hotFolder.resolve( eventPath.context() );
                    log.trace( "calling destination.transfer({})", path );
                    destination.transfer( path );
                    log.info( "transferred {} to destination" );

                    if (! key.reset()) {
                        break;
                    }
                }
            }
        }
        catch ( IOException ioe ) {
            log.error( ioe.getMessage(), ioe );
        }
        log.debug( "existing run loop" );
    }

    @Override
    public void start() throws InterruptedException {
        log.trace( "starting monitor" );
        thread = new Thread( this );
        thread.start();
        synchronized ( this ) {
            this.wait();
        }
        log.trace( "monitor started" );
    }

    @Override
    public void stop() throws InterruptedException {
        log.trace( "stopping monitor" );
        thread.interrupt();
        thread.join();
        thread = null;
        log.trace( "monitor stopped" );
    }
}

クラスは、イベントDestinationによって示されるパスから転送する方法を知っている私自身のものです。WatchService

つまり、本質的には、インスタンスのメソッドでWatchServiceループ全体をラップしただけです。runRunnable

于 2013-04-25T15:07:26.477 に答える