文件监听 Watch

方法入口

public class DirMonitor implements Runnable{
    @Override
    public void run() {
        new NowFileChangeProc().startMonitor("监听的目录");
    }
}

文件变动事件

public class NowFileChangeProc {
  public void startMonitor(String dir) {
        if (dir == null) {
            String msg = "error, the monitor dir con't is null!";
            ErrReporter.report(msg);
            return;
        }
        final File file = new File(dir);
        new Thread(new Runnable() {
            public void run() {
                try {
                    new WatchDir(file, true, new FileActionCallback() {
                        @Override
                        public void create(File file) {
                            if (file.isDirectory()) {
                                // 创建文件夹不处理
                                return;
                            }
                            String msg = "File create \t" + file.getAbsolutePath();
//							if(file.renameTo(file)) {
//								msg += "\r\n add to queue";
                            String absolutePath = file.getAbsolutePath();
                            if(absolutePath.endsWith("txt")) {
                                Timer timer = new Timer();
                                timer.schedule(new TimerTask() {
                                    @Override
                                    public void run() {
                                        // TODO Auto-generated method stub
                                        UploadsQueue.addCurrent(new File(absolutePath));
                                    }
                                }, 1000);
                            }
                            Configs.sysLog.info(msg+"---------监听新文件夹创建");
                        }
                        @Override
                        public void delete(File file) {
                            String msg = "File delete \t" + file.getAbsolutePath();
                            Configs.sysLog.info(msg);
                        }

                        @Override
                        public void modify(File file) {
                            String msg = "File update \t" + file.getAbsolutePath();
                            String absolutePath = file.getAbsolutePath();
                            if(absolutePath.endsWith("txt")) {
                                Timer timer = new Timer();
                                timer.schedule(new TimerTask() {
                                    @Override
                                    public void run() {
                                        // TODO Auto-generated method stub
                                        UploadsQueue.addCurrent(new File(absolutePath));
                                    }
                                }, 1000);
                            }
                            Configs.sysLog.info(msg+"---------监听新文件夹移动");
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        Configs.sysLog.info("--------------------------------------------------\nMonitoring:" + file.getAbsolutePath() + "\t >>> ");
    }
    public static void main(String[] args) throws Exception {
        new NowFileChangeProc().startMonitor("D:\\upload");
    }
}

文件操作的回调方法

/**
 * 文件操作的回调方法
 */
public abstract class FileActionCallback {

	public void delete(File file) {
	};

	public void modify(File file) {
	};

	public void create(File file) {
	};

}

文件变动行为枚举

public enum FileAction {
	DELETE("ENTRY_DELETE"), CREATE("ENTRY_CREATE"), MODIFY("ENTRY_MODIFY");
	private String value;
	FileAction(String value) {
		this.value = value;
	}	
	public String getValue() {
		return value;
	}
}

文件监听目录

/**
 * 文件夹监控
 *
 */
public class WatchDir {

	private final WatchService watcher;
	private final Map<WatchKey, Path> keys;
	private final boolean subDir;

	/**
	 * 构造方法
	 * 
	 * @param file
	 *            文件目录,不可以是文件
	 * @param subDir
	 * @throws Exception
	 */
	public WatchDir(File file, boolean subDir, FileActionCallback callback) throws Exception {
		if (!file.isDirectory()) {
			Exception newExce = new Exception(file.getAbsolutePath() + "is not a directory!");
			Configs.sysLog.info(ExceptionUtil.getExceptionTxt(newExce));
			throw newExce;
		}	
		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;
	}	
	/**
	 * 观察指定的目录
	 * 
	 * @param dir
	 * @throws IOException
	 */
	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) {
				// 操作未识别
				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(FileAction.DELETE.getValue())) {
					callback.delete(file);
				} else if (kind.name().equals(FileAction.CREATE.getValue())) {
					callback.create(file);
				} else if (kind.name().equals(FileAction.MODIFY.getValue())) {
					callback.modify(file);
				} else {
					continue;
				}
				// if directory is created, and watching recursively, then
				// register it and its sub-directories
				if (subDir && (kind == StandardWatchEventKinds.ENTRY_CREATE)) {
					try {
						if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
							registerAll(child);
						}
					} catch (IOException x) {
						// ignore to keep sample readbale
					}
				}
			}	
			boolean valid = key.reset();
			if (!valid) {
				// 移除不可访问的目录
				// 因为有可能目录被移除,就会无法访问
				keys.remove(key);
				// 如果待监控的目录都不存在了,就中断执行
				if (keys.isEmpty()) {
					String msg = "WatchDir break because keys isEmpty";
					Configs.sysLog.info(msg);
					break;
				}
			}
		}
	}	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值