Using the monitoring service provided by Java SE 7 to implement functions similar to. NET FileWatcher

Source: Internet
Author: User


Java SE 7 Tutorial adds an example of Directory change monitoring to introduce the newly released WatchService API.




However, for users who are used to. NET FileWatcher, if it is used for projects, I think it has two shortcomings:


1. An independent background thread running mechanism should be provided so that the monitoring process can be switched on the background without affecting front-end processing.


2. Java does not have a built-in source event mechanism like. NET, but it can use its built-in Observer/Observable object to implement quasi-events in Observer mode.





The following describes how to delete irrelevant content in the Java SE Tutorial example and add the implementation after the two extensions. This API is relatively new and I hope to discuss with you more:




1. Refer to. NET to define event parameter objects.


Package marvellousworks. practicalpattern. concept. unittest;


Import java. nio. file. WatchEvent. Kind;



* File System Event Type

* @ Author wangxiang



Public final class FileSystemEventArgs {

Private final String fileName;

Private final Kind <?> Kind;

Public FileSystemEventArgs (String fileName, Kind <?> Kind ){

This. fileName = fileName;

This. kind = kind;



* File path


Public String getFileName () {return fileName ;}


* Operation type: Change, create, and delete


@ SuppressWarnings ("rawtypes ")

Public Kind getKind () {return kind ;}




2. Define DirectoryWatcher to monitor a folder. As for how to extend FileWatcher, you can limit the file name and operation type.




Package marvellousworks. practicalpattern. concept. unittest;


Import java. io. IOException;

Import java. nio. file. FileSystems;

Import java. nio. file. Path;

Import java. nio. file. Paths;

Import java. nio. file. WatchEvent;

Import java. nio. file. WatchEvent. Kind;

Import java. nio. file. WatchKey;

Import java. nio. file. WatchService;

Import java. util. Observable;

Import java. util. concurrent. Callable;

Import java. util. concurrent. Executor;

Import java. util. concurrent. Executors;

Import java. util. concurrent. FutureTask;


Import static java. nio. file. StandardWatchEventKinds .*;



* Monitors the update, creation, and deletion of files in a directory (excluding subdirectories)


* Modified

* Make it closer to. NET's DirectoryWatcher usage habits


* Java does not have an event mechanism similar to. NET source.

* Therefore, Java SE's Observer/Observable object is used to throw a "false" event.


* Applicable to Java SE 7


* @ Author wangxiang



Public class DirectoryWatcher extends Observable {


Private WatchService watcher;

Private Path path;

Private WatchKey key;

Private Executor executor = Executors. newSingleThreadExecutor ();

FutureTask <Integer> task = new FutureTask <Integer> (

New Callable <Integer> (){

Public Integer call () throws InterruptedException {

ProcessEvents ();

Return Integer. valueOf (0 );}});


@ SuppressWarnings ("unchecked ")

Static <T> WatchEvent <T> cast (WatchEvent <?> Event ){

Return (WatchEvent <T>) event;



Public DirectoryWatcher (String dir) throws IOException {

Watcher = FileSystems. getDefault (). newWatchService ();

Path = Paths. get (dir );

// Monitors file update, creation, and deletion events in the directory

Key = path. register (watcher, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE );




* Start the monitoring process


Public void execute (){

// Start an additional thread to load the Watching process through the thread pool

Executor.exe cute (task );



* The closed object cannot be restarted.

* @ Throws IOException


Public void shutdown () throws IOException {

Watcher. close ();

Executor = null;




* Monitors File System Events


Void processEvents (){

While (true ){

// Wait until the event signal is obtained

WatchKey signal;

Try {

Signal = watcher. take ();

} Catch (InterruptedException x ){




For (WatchEvent <?> Event: signal. pollEvents ()){

Kind <?> Kind = event. kind ();


// TBD-provide example of how OVERFLOW event is handled

If (kind = OVERFLOW ){




// Context for directory entry event is the file name of entry

WatchEvent <Path> ev = cast (event );

Path name = ev. context ();

Notifiy (name. getFileName (). toString (), kind );


// Prepare for the next monitoring notification

Key. reset ();




* Notifies the external Observer directories of new event updates.


Void notifiy (String fileName, Kind <?> Kind ){

// The annotation directory has been changed.

SetChanged ();

// Actively notify the observer of changes to the target object status

// Here we use the "push" method of the observer mode.

NotifyObservers (new FileSystemEventArgs (fileName, kind ));





3. Unit Test


Package marvellousworks. practicalpattern. concept. unittest;


Import static org. junit. Assert .*;


Import java. io. File;

Import java. io. IOException;

Import java. util. ArrayList;

Import java. util. List;

Import java. util. Observable;

Import java. util. Observer;


Import org. junit. Test;

Import static java. nio. file. StandardWatchEventKinds .*;


Public class DirectoryWatcherFixture {


Private static final String DIR_PATH = System. getProperty ("user. dir ");

Private static final File DIR = new File (DIR_PATH );

Private static final String SUFFIX = ". txt ";

Private static final String PREFIX = "test ";

Private static final int ADD_TIMES = 3;



* Observer

* @ Author wangxiang



Public class Logger implements Observer {

@ Override

Public void update (Observable observable, Object eventArgs ){

FileSystemEventArgs args = (FileSystemEventArgs) eventArgs;

System. out. printf ("% s has been % s \ n", args. getFileName (), args. getKind ());

AssertTrue (args. getFileName (). startsWith (PREFIX ));

AssertEquals (ENTRY_CREATE, args. getKind ());



@ Test

Public void testWatchFile () throws IOException, InterruptedException {

DirectoryWatcher watcher = new DirectoryWatcher (DIR_PATH );

Logger l1 = new Logger ();

Watcher. addObserver (l1 );

Watcher.exe cute ();

// Create a series of temporary files

List <String> files = new ArrayList <> ();

For (int I = 0; I <ADD_TIMES; I ++ ){

Files. add (File. createTempFile (PREFIX, SUFFIX, DIR). toString ());


// Wait for the execution of background tasks.

Thread. sleep (4000 );

Watcher. shutdown ();

System. out. println ("finished ");





Test content displayed in the Console window




Test5769907807190550725.txt has been ENTRY_CREATE

Test100007672246246330348.txt has been ENTRY_CREATE

Test1823102943601166149.txt has been ENTRY_CREATE


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.