Java实现监听文件变化的三种方案详解
在Java编程中,经常需要对文件进行监听,以便在文件发生更新时及时做出相应的处理。下面将介绍三种实现文件监听的方案,分别是Java 7的WatchService、commons-io库、以及第三方库jnotify。
1. Java 7的WatchService
Java 7引入了WatchService API,它可以用来监听文件目录中的所有变化,包括文件的创建、修改、删除、重命名等。下面是基本的WatchService示例:
import java.io.*;
import java.nio.file.*;
public class FileWatcherTest {
public static void main(String[] args) throws IOException, InterruptedException {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("/Users/username/test/");
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
while (true) {
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException ex) {
return;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
WatchEvent<Path> e = (WatchEvent<Path>)event;
Path filename = e.context();
// 打印出文件变化事件类型和文件名
System.out.println(kind + " -> " + filename);
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
}
}
上述代码将监听指定目录(/Users/username/test/)中所有文件的创建、修改、删除事件,并且当这些事件发生时,会打印出事件类型和文件名。在这个示例中,我们使用了WatchService的take()方法来阻塞等待事件的发生,一旦事件发生即会被唤醒。
2. commons-io库
Apache Commons IO库提供了一个监视器(FileMonitor)类,可以监听指定目录中的文件变化。这个监视器在后台运行,可以周期性地扫描指定的目录,并且对发生变化的文件会回调一个指定的监听器类。
下面是一个简单的示例,演示了如何监听指定目录中所有的txt文件:
import org.apache.commons.io.monitor.*;
import java.io.*;
public class MonitorTest {
public static void main(String[] args) throws Exception {
File folder = new File("/Users/username/test/");
FileAlterationObserver observer = new FileAlterationObserver(folder);
// 过滤规则,只对txt文件进行监听
FileFilter filter = FileFilterUtils.suffixFileFilter(".txt");
observer.setFileFilter(filter);
// 监听器
FileAlterationListener listener = new FileAlterationListenerAdaptor() {
public void onFileCreate(File file) {
System.out.println("File created: " + file.getAbsolutePath());
}
public void onFileChange(File file) {
System.out.println("File changed: " + file.getAbsolutePath());
}
public void onFileDelete(File file) {
System.out.println("File deleted: " + file.getAbsolutePath());
}
};
observer.addListener(listener);
// 开始监听
FileAlterationMonitor monitor = new FileAlterationMonitor(5000); // 5秒扫描一次
monitor.addObserver(observer);
monitor.start();
}
}
上述代码使用了FileAlterationObserver类来监控指定目录文件的变化,添加了过滤规则只监听指定后缀名的txt文件,实现了三种事件回调的方法。代码中使用了FileAlterationMonitor来启动监控进程,每隔5秒监听一次文件变化。
3. jnotify
jnotify是一个跨平台的文件系统监听库,为JVM提供了更高效、更可靠的文件监控机制。jnotify需要本地库的支持,所以使用前需要根据操作系统的不同下载对应的jni实现,并引用库文件。
下面是jnotify的一个示例,演示了如何监听指定目录中所有的txt文件:
import net.contentobjects.jnotify.*;
public class JNotifyTest {
public static void main(String[] args) throws Exception {
String path = "/Users/username/test/";
JNotify.addWatch(path,
JNotify.FILE_CREATED,
JNotify.FILE_DELETED,
JNotify.FILE_MODIFIED,
JNotify.FILE_RENAMED);
JNotifyListener listener = new JNotifyListener() {
public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
System.out.println("File renamed: " + oldName + " -> " + newName);
}
public void fileModified(int wd, String rootPath, String name) {
System.out.println("File modified: " + name);
}
public void fileDeleted(int wd, String rootPath, String name) {
System.out.println("File deleted: " + name);
}
public void fileCreated(int wd, String rootPath, String name) {
System.out.println("File created: " + name);
}
};
// 开始监听
int watchId = JNotify.addWatch(path, JNotify.FILE_ANY, true, listener);
// 等待事件
Thread.sleep(1000000);
// 删除监听
boolean res = JNotify.removeWatch(watchId);
if (!res) {
System.out.println("Error removing watch");
}
}
}
上述代码使用了jnotify的addWatch()方法来添加对指定目录的监听,指定了四种事件类型,并且实现了指定路径下发生变化回调的listener。在示例中,我们等待1000000毫秒,让程序一直监听文件变化,当监听到变化时将输出事件类型和文件名。在示例结束后,我们使用jnotify的removeWatch()方法来终止监听。
以上是三种实现文件监听的方法,各有其优缺点,可以根据具体需求选择适当的方法。在实际项目中,我们可以根据文件系统的特点和自身业务逻辑的需求来选择最适合的方案。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现监听文件变化的三种方案详解 - Python技术站