Java 7 WatchService - Ignoring multiple occurrences of the same event

后端 未结 14 635
情歌与酒
情歌与酒 2020-12-05 02:21

The javadoc for StandardWatchEventKinds.ENTRY_MODIFY says:

Directory entry modified. When a directory is registered for this event the

14条回答
  •  难免孤独
    2020-12-05 02:43

    WatcherServices reports events twice because the underlying file is updated twice. Once for the content and once for the file modified time. These events happen within a short time span. To solve this, sleep between the poll() or take() calls and the key.pollEvents() call. For example:

    @Override
    @SuppressWarnings( "SleepWhileInLoop" )
    public void run() {
      setListening( true );
    
      while( isListening() ) {
        try {
          final WatchKey key = getWatchService().take();
          final Path path = get( key );
    
          // Prevent receiving two separate ENTRY_MODIFY events: file modified
          // and timestamp updated. Instead, receive one ENTRY_MODIFY event
          // with two counts.
          Thread.sleep( 50 );
    
          for( final WatchEvent event : key.pollEvents() ) {
            final Path changed = path.resolve( (Path)event.context() );
    
            if( event.kind() == ENTRY_MODIFY && isListening( changed ) ) {
              System.out.println( "Changed: " + changed );
            }
          }
    
          if( !key.reset() ) {
            ignore( path );
          }
        } catch( IOException | InterruptedException ex ) {
          // Stop eavesdropping.
          setListening( false );
        }
      }
    }
    

    Calling sleep() helps eliminate the double calls. The delay might have to be as high as three seconds.

提交回复
热议问题