public void addObserver(FileChangeObserver observer, String filename, long delay) throws FileNotFoundException {
TimerTask task = new FileChangeTask(observer , filename );
List<TimerTask> tasks = fileObservers.get(filename );
if(tasks ==null){
tasks = new ArrayList<TimerTask>();
}
tasks.add( task);
fileObservers.put(filename , tasks );
timer.schedule( task, delay, delay);
}
在FileChangeTask的run()函数中,通过比对时间戳来判断文件是否修改,若发生改动,则通知其Observer进行相应处理。
public void run() { try { long newLastModified = file.lastModified(); if (newLastModified > lastModified )[ ] { lastModified = newLastModified ;[ ] observer.fileChanged( file.getPath()); } } catch (Exception e ) { System. err.println(e .getMessage()); } }测试用例FileMonitorTest中为sample1.txt添加了consoleObserver和emailObserver,为sample2.txt添加了consoleObserver。然后对这两个文件分别进行修改。
package com.cwind.file; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import org.junit.After; import org.junit.Before; import org.junit.Test; public class FileMonitorTest { File sampleFile1, sampleFile2 ; FileChangeMonitor monitor; ConsoleFileChangeObserver consoleObserver; EmailFileChangeObserver emailObserver; @Before public void setUp() throws Exception { sampleFile1 = new File("sample1.txt" ); sampleFile2 = new File("sample2.txt" ); monitor = FileChangeMonitor. getInstance(); consoleObserver = new ConsoleFileChangeObserver(); emailObserver = new EmailFileChangeObserver("billchen01@163.com"); } @After public void tearDown() throws Exception { } @Test public void testMonitorSampleFile() throws InterruptedException, IOException{ monitor.addObserver( consoleObserver, sampleFile1 .getPath(), FileChangeMonitor.DELAY_TIME ); monitor.addObserver( emailObserver, sampleFile1 .getPath(), FileChangeMonitor.DELAY_TIME ); monitor.addObserver( consoleObserver, sampleFile2 .getPath(), FileChangeMonitor.DELAY_TIME ); FileOutputStream fos1 = new FileOutputStream(sampleFile1 ); FileOutputStream fos2 = new FileOutputStream(sampleFile2 ); fos1.write(0); fos2.write(0); fos1.flush(); fos2.flush(); fos1.close(); fos2.close(); Thread. sleep(3000); } }输出结果如下:
Console: File sample1.txt is changed, will print warning message to console. File sample1.txt is changed, will send email to billchen01@163.com. Console: File sample2.txt is changed, will print warning message to console.JDK 1.7 及之后版本:基于WatchService实现
package com.cwind.file; import java.io.IOException; 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; public class WatchServerTest { public static void main(String[] args) throws InterruptedException, IOException { WatchService watchService = FileSystems.getDefault().newWatchService(); final Path path = Paths.get( "."); final WatchKey watchKey = path.register( watchService, StandardWatchEventKinds.ENTRY_MODIFY , StandardWatchEventKinds. ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE ); boolean fileNotChanged = true; int count = 0; while (fileNotChanged ) { final WatchKey wk = watchService .take(); System. out.println("Loop count: " + count ); for (WatchEvent<?> event : wk .pollEvents()) { final Path changed = (Path) event.context(); System. out.println(changed + ", " + event .kind()); if (changed .endsWith("sample1.txt")) { System. out.println("Sample file has changed" ); } } // reset the key boolean valid = wk .reset(); if (!valid ) { System. out.println("Key has been unregisterede" ); } count++; } } }?总结,使用WatchService步骤如下:
原文:http://cwind.iteye.com/blog/2179068