版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rexueqingchun/article/details/82498519
1.配置监听器
web项目配置监听器
web.xml添加
<listener>
<listener-class>cn.com.test.InitListener</listener-class>
</listener>
实现ServletContextListener接口
package cn.com.test;
import java.io.File;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class InitListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent arg0) {
final File file = new File("D:\\cs");
new Thread(new Runnable() {
@Override
public void run() {
try {
new WatchDir(file, true, new FileActionCallback() {
@Override
public void create(File file) {
System.out.println("文件已创建\t" + file.getAbsolutePath());
}
@Override
public void delete(File file) {
System.out.println("文件已删除\t" + file.getAbsolutePath());
}
@Override
public void modify(File file) {
System.out.println("文件已修改\t" + file.getAbsolutePath());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
System.out.println("正在监视文件夹:" + file.getAbsolutePath());
}
}
spring boot项目配置监听器
启动类添加@WebListener注解支持
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RestController;
import cn.com.app.constant.TaskThreadPoolConfig;
@RestController
@SpringBootApplication
@EnableScheduling //开启定时任务支持
@EnableAsync //开启多线程异步任务支持
@ServletComponentScan //开启对监听器@WebListener注解支持
@EnableConfigurationProperties(TaskThreadPoolConfig.class) // 开启配置属性支持
@MapperScan("cn.com.app.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
通过@WebListener注解开启监听
import java.io.File;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent arg0) {
final File file = new File("D:\\cs");
new Thread(new Runnable() {
@Override
public void run() {
try {
new WatchDir(file, true, new FileActionCallback() {
@Override
public void create(File file) {
System.out.println("文件已创建\t" + file.getAbsolutePath());
}
@Override
public void delete(File file) {
System.out.println("文件已删除\t" + file.getAbsolutePath());
}
@Override
public void modify(File file) {
System.out.println("文件已修改\t" + file.getAbsolutePath());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
System.out.println("正在监视文件夹:" + file.getAbsolutePath());
}
}
2.创建监控文件夹核心类
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
/**
* 文件夹监控
*/
public class WatchDir {
private final WatchService watcher;
private final Map<WatchKey, Path> keys;
private final boolean subDir;
/**
* 构造方法
* @param file 文件目录,不可以是文件
*/
public WatchDir(File file, boolean subDir, FileActionCallback callback) throws Exception {
if (!file.isDirectory())
throw new Exception(file.getAbsolutePath() + "不是文件夹!");
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey, Path>();
this.subDir = subDir;
Path dir = Paths.get(file.getAbsolutePath());
if (subDir) {
registerAll(dir);
} else {
register(dir);
}
processEvents(callback);
}
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) {
return (WatchEvent<T>) event;
}
/**
* 观察指定的目录
*/
private void register(Path dir) throws IOException {
WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
keys.put(key, dir);
}
/**
* 观察指定的目录,并且包括子目录
*/
private void registerAll(final Path start) throws IOException {
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
register(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
* 发生文件变化的回调函数
*/
@SuppressWarnings("rawtypes")
void processEvents(FileActionCallback callback) {
for (;;) {
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
Path dir = keys.get(key);
if (dir == null) {
System.err.println("操作未识别");
continue;
}
for (WatchEvent<?> event : key.pollEvents()) {
Kind kind = event.kind();
// 事件可能丢失或遗弃
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
// 目录内的变化可能是文件或者目录
WatchEvent<Path> ev = cast(event);
Path name = ev.context();
Path child = dir.resolve(name);
File file = child.toFile();
if (kind.name().equals("ENTRY_DELETE")) {
callback.delete(file);
} else if (kind.name().equals("ENTRY_CREATE")) {
callback.create(file);
} else if (kind.name().equals("ENTRY_MODIFY")) {
callback.modify(file);
} else {
continue;
}
if (subDir && (kind == StandardWatchEventKinds.ENTRY_CREATE)) {
try {
if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
registerAll(child);
}
} catch (IOException x) {
}
}
}
boolean valid = key.reset();
if (!valid) {
// 移除不可访问的目录
// 因为有可能目录被移除,就会无法访问
keys.remove(key);
// 如果待监控的目录都不存在了,就中断执行
if (keys.isEmpty()) {
break;
}
}
}
}
}
3.创建文件操作回调方法
import java.io.File;
/**
* 文件操作的回调方法
*/
public abstract class FileActionCallback {
public void delete(File file) {
};
public void modify(File file) {
};
public void create(File file) {
};
}
备注:由于WatchService为jdk7添加,因此需要jdk版本为7及以上