转自:http://www.iyouf.info/java-implement-file-monitor.html
在网络上使用java来监控文件状态的文章 例子 太少了。就是有也只是走走过场而已。
今天我特意把这段代码从日志采集系统里面分离出来。供大家参阅,交流,学习。
思路大概是这样的: 通过一个线程 每隔一段时间给某个目录下的文件照个快照 也就是获取这些文件的绝对路径和最后修改的时间,比较前后两次的快照
如果第二次的快照中加入了一个文件,而第一次快照中没有 说明是此文件是新添加的 就触发添加事件,
如果两次的快照中都有这个文件 ,那么就比较次文件前后两次的时间戳,要是不同的话就说明此文件已经改动过了,触发修改事件
第一次的快照中有 而第二次的快照中没有,那么此文件被删掉了,触发文件删除事件
这里的快照我使用一个HashMap来存储当前文件的绝对路径和该文件最后被修改的时间
先定义两个接口 一个是事件的监听器FileLIstener 和文件的触发事件FileEvent
代码里面有相信的注释 这里文字就不写了 ,直接贴代码了
public interface FileListener {
public void addListener(FileEvent listener);
public void removeListener(FileEvent listener);
}
public interface FileEvent {
//添加事件
public void onAddEvent(Object add);
//修改事件
public void onChangeEvent(Object changed);
//删除事件
public void onDeleteEvent(Object deleted);
}FileEvent的实现
public class FileEventImpl implements FileEvent {
protected static final Logger log4j = Logger.getLogger(FileEventImpl.class);
public FileEventImpl() {
super();
}
/**
* 文件被添加时触发的事件
*/
public void onAddEvent(Object add) {
if (add instanceof File) {
File file = (File) add;
if (file.isFile()) {
log4j.info(fileAbsolutePath + " is added!");
}
}
}
/**
* 文件修改时的触发事件
*/
public void onChangeEvent(Object changed) {
if (changed instanceof File) {
File file = (File) changed;
if (file.isFile()) {
String fileAbsolutePath = file.getAbsolutePath();
log4j.info(fileAbsolutePath + " is changed");
}
}
}
public void onDeleteEvent(Object deleted) {
if (deleted instanceof String) {
String deletedFile = (String) deleted;
log4j.info(deletedFile + " is deleted");
}
}
}不停的监控线程
public abstract class IntervalThread implements Runnable {
//线程的状态
private boolean active = false;
//线程睡眠的时间
private int interval = -1;
private Thread runner;
public IntervalThread(int intervalSeconds) {
this.interval = intervalSeconds * 1000;
}
/**
* 线程启动
*/
public void start() {
active = true;
if (runner == null && interval > 0) {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
active = false;
}
public void run() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
while (active) {
try {
doInterval();
Thread.sleep(interval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
protected abstract void doInterval();
}
public abstract class AbstractResourceWatcher extends IntervalThread implements
FileListener {
private List<FileEvent> listeners = new LinkedList<FileEvent>();
public AbstractResourceWatcher(int intervalSeconds) {
super(intervalSeconds);
}
//清空绑定监听器
public void removeAllListeners() {
listeners.clear();
}
public void addListener(FileEvent listener) {
listeners.add(listener);
}
public void removeListener(FileEvent listener) {
listeners.remove(listener);
}
/**
* 当一个资源被添加到这,此方法将被调用. 它会触发onAdd()方法
*/
protected void resourceAdded(Object add) {
for (Iterator<FileEvent> it = listeners.iterator(); it
.hasNext();) {
it.next().onAddEvent(add);
}
}
/**
* 当一个文件被改变的时候 它会触发onChange方法
*
* @param changedResource
*/
protected void resourceChanged(Object changed) {
for (Iterator<FileEvent> it = listeners.iterator(); it
.hasNext();) {
it.next().onChangeEvent(changed);
}
}
/**
* 一个文件被删除时的触发事件
* @param deleted
*/
protected void resourceDeleted(Object deleted) {
for (Iterator<FileEvent> it = listeners.iterator(); it
.hasNext();) {
it.next().onDeleteEvent(deleted);
}
}
protected abstract void doInterval();
}最后 这个类就是最关键的了
/**
* 这个类 主要是监控 目录中文件的变化情况
* @author dengm
*
*/
public class DirectoryWatcher extends AbstractResourceWatcher {
protected static final Logger log4j = Logger.getLogger(DirectoryWatcher.class);
//当前文件的快照
private Map<String,Long> currentFiles = new HashMap<String,Long>();
//上一次文件的快照
private Map<String,Long> prevFiles = new HashMap<String,Long>();
private String directory;
public DirectoryWatcher(String directoryPath, int seconds)
throws RuntimeException {
//线程运行的时间间隔
super(seconds);
File logDirectory = new File(directoryPath);
//检查当前的日志目录是否存在
if (logDirectory != null && !logDirectory.isDirectory()) {
//不存在的话就给他创建一个
logDirectory.mkdir();
}
this.directory = directoryPath;
log4j.info("Start to monitor " +this.directory);
}
public void start() {
//记录当前文件的时间戳
takeSnapshot();
//启动线程
super.start();
}
//让线程停止工作 ....暂时还没用上
public void stop() {
super.stop();
}
/**
* 存储文件名和最后修改的所有文件
*/
private void takeSnapshot() {
//清空上一次的快照,把当前的快照设置为上次的
prevFiles.clear();
prevFiles.putAll(currentFiles);
//清空当前的快照信息
currentFiles.clear();
File dir = new File(directory);
iteratorDirectory(dir);
}
private void iteratorDirectory(File directory){
File[] files = directory.listFiles();
//保存当前文件和最后修改的时间戳
for(File file: files){
//如果是目录 递归
if(file.isDirectory()){
iteratorDirectory(file);
}else{
currentFiles.put(file.getAbsolutePath(),
new Long(file.lastModified()));
}
}
}
private void checkFileStatus(String fileName,Long lastModified){
//如果没有这个文件名,说明是刚刚添加的
if (!prevFiles.containsKey(fileName)) {
resourceAdded(new File(fileName));
}else if (prevFiles.containsKey(fileName)) {
//包含这个文件,然后前后的时间比较一下
Long prevModified = (Long) prevFiles.get(fileName);
//如果时间不等说明被修改了
if (prevModified.compareTo(lastModified) != 0) {
resourceChanged(new File(fileName));
}
}
}
private void checkFile(){
Set<Entry<String,Long>> set = currentFiles.entrySet();
//遍历当前的文件列表
Iterator<Entry<String, Long>> currentIt = set.iterator();
while (currentIt.hasNext()) {
Map.Entry<String, Long> entry = currentIt.next();
String fileName = entry.getKey();
Long lastModified = entry.getValue();
File file = new File(fileName);
//又是递归..
if(file.isDirectory()){
File files[] = file.listFiles();
for(File f: files){
checkFileStatus(f.getAbsolutePath(),lastModified);
}
}else{
checkFileStatus(fileName,lastModified);
}
}
Set<Entry<String,Long>> preSet = prevFiles.entrySet();
Iterator<Entry<String, Long>> prevIt = preSet.iterator();
while (prevIt.hasNext()) {
Map.Entry<String, Long> entry = prevIt.next();
String fileName = entry.getKey();
//文件被删了.
if (!currentFiles.containsKey(fileName)) {
resourceDeleted(fileName);
}
}
}
/**
* 检查目录中的任何变化
*/
protected void doInterval() {
//又照个快照
takeSnapshot();
//当前的快照和上次的快照对比 就是比较两次的时间戳
checkFile();
}
}测试代码
public static void main(String[] args) {
DirectoryWatcher dw = new DirectoryWatcher("/opt/raphael", 5);
//添加一个文件监听
dw.addListener(new FileEventImpl());
dw.start();
}
分享到:
相关推荐
Java实现实时监控目录下文件变化的方法 Java实现实时监控目录下文件变化的方法是指通过Java语言来实现实时监控目录下文件的变化情况,包括文件的创建、删除、修改等操作。这种方法可以应用于各种场景,例如文件系统...
在本项目"乘客打车和司机抢单的Java实现.zip"中,...以上是对"乘客打车和司机抢单的Java实现.zip"项目中可能包含的一些核心知识点的详细说明,具体的实现细节还需要参考解压后的代码文件"taxi-master"来进一步分析。
通过这个压缩包,学习者不仅可以了解如何用Java实现一个CS架构的远程监控系统,还可以学习到软件开发的完整流程,包括需求分析、设计、编码、测试和文档编写。对于想要深入Java编程或研究远程监控技术的人来说,这是...
Java-ONVIF 云台控制是针对网络视频监控设备的一种技术实现,主要涉及Java编程语言与ONVIF(Open Network Video Interface Forum)协议的整合。ONVIF是一种国际开放性标准,它定义了IP视频监控设备之间的通信接口,...
提供的"Demo"很可能是用某种编程语言(如Python、Java、C#等)实现的一个示例程序,用于演示如何使用Dir Watcher库来监控文件夹变化。它可能包括以下部分: 1. 初始化:设置要监控的文件夹路径,并配置感兴趣的事件...
综上所述,实现"web项目中定时删除某指定路径下的文件"这一功能,需要结合定时任务框架、文件操作API、路径处理、权限控制、异常处理、日志记录等多个技术点。在实际开发中,应根据具体的技术栈和业务需求来设计和...
本篇文章将深入探讨如何使用FFmpeg这个强大的跨平台命令行工具,并结合Java进行调用来实现这一功能。FFmpeg是一个开源项目,提供了音频、视频处理的各种功能,包括编码、解码、转换和流处理等。 首先,我们需要在...
通过Java SDK,开发者可以调用相关API获取摄像头支持的所有预置点,这在多场景监控中非常实用。 2. **设置预置点名称**:为了方便记忆和管理,用户可以为每个预置点赋予特定的名称。SDK提供了接口来设定这些名称,...
在本项目中,我们关注的是"Java_某动画游戏的服务器软件重新实现"。这个话题涉及到使用Java语言来重构或重写一个动画游戏的服务器软件。服务器软件在游戏行业中起着至关重要的作用,它处理玩家的数据交互、游戏状态...
在这个"FastDFS文件服务器Java客户端.zip"压缩包中,包含了FastDFS的Java客户端源码,方便Java开发者在自己的项目中集成FastDFS,实现文件上传和下载等功能。 FastDFS的核心组件包括跟踪服务器(Tracker Server)和...
在Java编程语言中,获取文件的最后修改时间是一项常见的任务,这对于文件管理和系统监控非常有用。我们可以使用`java.io.File`类提供的方法来实现这一功能。以下是对标题和描述中涉及的知识点的详细说明: ### 文件...
总之,Java实现的网页爬虫1.5版本聚焦爬虫是一个深入研究和实践Web信息提取的项目。通过合理的设计和优化,它可以有效地从互联网中抽取特定主题的内容,为各种数据分析任务提供数据支持。对于想要学习或提升爬虫技能...
综合以上信息,这个Java项目展示了如何利用网络编程、多线程、异步处理等技术来实现一个实时监控和快速响应的火车票抢票系统。同时,它也涉及到了软件工程中的版本控制、项目构建、配置管理等多个方面。对于学习Java...
标题中的“基于Java实现的可以直接运行的抓包工具”指的是使用Java编程语言开发的一款网络抓包应用程序。这类工具主要用于捕获网络上的数据包,以便分析网络通信情况、检测网络安全问题或者进行网络性能优化。Java是...
- 配置服务器:设置tracker服务器和storage服务器的配置文件,如`/etc/fdfs`目录下的`tracker.conf`和`storage.conf`。 - 初始化数据:在storage服务器上执行初始化命令,创建必要的目录结构和文件。 - 启动服务:...
"海康威视java开发v5.36.30"是一个针对海康威视监控设备进行Java开发的软件包,主要服务于开发人员,帮助他们在Java环境中实现对海康威视监控设备的控制和数据交互。 该版本的SDK(Software Development Kit)为CH-...
将该文件解压后放入Tomcat的webapps目录,意味着系统前端的Web应用将被Tomcat服务加载并提供给用户访问。 四、系统架构 机房监控系统通常采用B/S(浏览器/服务器)架构,前端通过Web页面与后端服务器进行通信。前端...
综上所述,定时监测文件大小是通过定时器实现的一种机制,它能够帮助我们实时监控文件的变化,对于监控系统、数据分析等领域具有重要意义。通过合理的设计和编程,我们可以构建出高效、可靠的文件大小监测系统。
1. 文件系统监控:为了实现“每隔一秒自动扫描指定的文件夹”,我们需要使用文件系统监控技术。在Java中,我们可以利用`java.nio.file.WatchService` API来监听文件夹的变化。当文件夹内有新PDF文件生成或更新时,...