转载:https://www.cnblogs.com/jnhs/p/11417078.html
我们在做数据接入或者文件解析的时候,经常需要对目录下的文件进行监控和解析。在对文件监控时,以前的做法是通过定时轮询该目录下,获取该目录的文件,该方法会有延时。JNotify给出java版的解决方案,引用Notify机制。
可以监听的文件信息包括
- 文件夹/文件创建
- 文件夹/文件删除
- 文件夹/文件修改 (文件内容被修改和文件夹被修改都可以检测到)
- 文件夹/文件重命名
使用Java实现
- 导入maven依赖
<dependency>
<groupId>net.contentobjects.jnotify</groupId>
<artifactId>jnotify</artifactId>
<version>0.94</version>
</dependency>
- 因为Jnotify是C语言开发的,所以需要在系统中加入jnotify_64bit.dll(64位) (Windows)或者libjnotify.so(linux)动态库。
- jnotify_64bit.dll(64位) 加入到C:\Windows\System32中
- libjnotify.so加入到/lib64目录中
3.代码实现
- 编写一个类继承JNotifyAdapter
- 重写方法
- 设置监听文件夹、添加需要监听的事件、是否监听子文件夹、 添加启动监视程序方法
package cn.itsqq.util;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyAdapter;
import net.contentobjects.jnotify.JNotifyException;
/**
* ClassName: jnotify <br/>
* Description: <br/>
* date: 2020/6/10 10:21<br/>
* @author shangqq<br />
*/
public class JnotifyTest extends JNotifyAdapter {
//可以写到配置文件中
private static final String REQUEST_BASE_PATH = "D:\\test";
/**
* 被监视的目录
*/
String path = REQUEST_BASE_PATH;
/**
* 关注目录的事件
*/
int mask =JNotify.FILE_CREATED |JNotify.FILE_DELETED| JNotify.FILE_RENAMED| JNotify.FILE_MODIFIED;
/**
* 是否监视子目录,即级联监视
*/
boolean watchSubtree = true;
/**
* 监听程序Id
*/
public int watchID;
/**
* 容器启动时启动监视程序
*/
public void beginWatch() {
/**
* 添加到监视队列中
*/
try {
this.watchID = JNotify.addWatch(path, mask, watchSubtree, this);
System.err.println("jnotify -----------启动成功2-----------");
} catch (JNotifyException e) {
e.printStackTrace();
}
/**
* 死循环,线程一直执行,休眠一分钟后继续执行,主要是为了让主线程一直执行 休眠时间和监测文件发生的效率无
* (就是说不是监视目录文件改变一分钟后才监测到,监测几乎是实时的,调用本地系统库)
*/
while (true) {
try {
//主要缓和主线程的执行效率,
Thread.sleep(600);
} catch (InterruptedException e) {// ignore it
}
}
}
/**
* 文件创建
* @param wd 监听程序Id 初始为1,多个监控程序以此加1
* @param rootPath 目录名
* @param name 文件名
*/
@Override
public void fileCreated(int wd, String rootPath, String name) {
System.err.println(wd+"----->文件被创建, 创建位置为: " + rootPath + "\\" + name);
}
/**
* 删除文件
* @param wd 监听程序Id 初始为1,多个监控程序以此加1
* @param rootPath 目录名
* @param name 文件名
*/
@Override
public void fileDeleted(int wd, String rootPath, String name) {
System.err.println(wd+"----->文件被删除, 被删除的文件名为:" + rootPath + name);
}
/**
* 文件修改 (文件内容被修改和文件夹被修改都可以检测到)
* @param wd 监听程序Id 初始为1,多个监控程序以此加1
* @param rootPath 目录名
* @param name 文件名
*/
@Override
public void fileModified(int wd, String rootPath, String name) {
System.err.println(wd+"----->文件内容被修改, 文件名为:" + rootPath + "\\" + name);
}
/**
* 文件重命名
* @param wd 监听程序Id 初始为1,多个监控程序以此加1
* @param rootPath 目录名
* @param oldName 修改前目录名
* @param newName 修改后目录名
*/
@Override
public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
System.err.println(wd+"----->文件被重命名, 原文件名为:" + rootPath + "\\" + oldName
+ ", 现文件名为:" + rootPath + "\\" + newName);
}
}
主程序启动监听程序
package cn.itsqq.controller;
import cn.itsqq.util.Jnotify;
public class Main2 {
public static void main(String[] args){
//开一个线程,为了不影响主程序运行
new Thread(){
@Override
public void run() {
JnotifyTest jnotifyTest = new JnotifyTest ();
jnotifyTest.beginWatch();
}
}.start();
}
}
最近也使用commons-io 实现监测文件变化,效果也可以,但是JNotify调用dll动态库,效率要更加的高,推荐使用JNotify
网友评论