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.