Java 对指定目录文件夹的监控

package com.***.cs.structs.esb;

import Common.MailService;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;

public class Ats_TRT_Floder_Listener {
    public static void main(String[] args) throws Exception {

        // 将文件目录读取出来,存储为一个map结构
        String file_path = "指定文件目录";
        Map<String, Map> file_path_map = new HashMap<String, Map>();
        file_path_map = readFiles(file_path, file_path_map);

        //创建一个文件系统的监听服务
        WatchService watchService = FileSystems.getDefault().newWatchService();

        Path path = Paths.get(file_path);

        //为该文件夹注册监听,监听新建、修改、删除事件。只能为文件夹(目录)注册监听,不能为单个文件注册监听
        path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);

        //编写事件处理
        while (true) {  //一直监听
            //拉取一个WatchKey。当触发监听的事件时,就会产生一个WatchKey,此WatchKey封装了事件信息。
            WatchKey watchKey = watchService.take();

            //使用循环是因为这一个WatchKey中可能有多个文件变化了,比如Ctrl+A全选,然后删除,只触发了一个WatchKey,但有多个文件变化了
            for (WatchEvent event : watchKey.pollEvents()) {
                System.out.println(event.context() + "发生了" + event.kind() + "事件!");

                if ("ENTRY_MODIFY".equals(event.kind()+"")){
                    String s = event.context().toString();
                    Map file_map = file_path_map.get(file_path + "\\" + s);  // 获取修改文件夹的文件
                    //  获取当前时间指定文件夹下的文件数量
                    File file = new File(file_path + "\\" + s);
                    File[] files = file.listFiles();
                    List<File> files1 = Arrays.asList(files);
                    ArrayList<String> files_String = new ArrayList<String>();
                    for (File file1 : files1) {
                        files_String.add(file1.getPath());
                    }
                    if (files1.size() < file_map.size()){
                        // 说明有文件被删除了
                        Set<String> fileName = file_map.keySet();
                        Iterator<String> iterator = fileName.iterator();
                        while (iterator.hasNext()){
                            String next = iterator.next();
                            boolean contains = files_String.contains(next);
                            if (!contains){
                                // 不包含
                                String [] to = {"收邮件地址"};
                                MailService.sendmail("TRT 图片删除", "发邮件的地址",
                                        to, null, next, null, "text/html;charset=utf-8");
                            }
                        }

                    }
                    file_path_map.clear();
                    file_path_map = readFiles(file_path, file_path_map);
                }
                if("ENTRY_CREATE".equals(event.kind()+"")){  //  当有新建时 更新文件的map结构
                    file_path_map.clear();
                    file_path_map = readFiles(file_path, file_path_map);
                }
                /*
                watchKey.pollEvents()  获取此次WatchKey中所有变化了的文件的信息,以List(列表)形式返回,一个WatchEvent就是一个元素,封装了一个变化了的文件的信息
                event.context()  获取文件名
                event.kind()  获取发生的事件类型

                因为只能为文件夹注册监听,如果要监听某些指定的文件,可以在增强的for循环中,先根据event.context()判断是否是指定的文件,是才处理。
                 */
            }

            //虽然是while()循环,但WatchKey和ByteBuffer一样,使用完要重置状态,才能继续用。
            watchKey.reset();    //如果不重置,WatchKey使用一次过后就不能再使用,即只能监听到一次文件变化。
        }


        /*
        测试:在D:/untitled/test目录下
        1、新建1.txt文件      1.txt.txt发生了ENTRY_CREATE事件!
        2、打开1.txt,输入"hello world!",并保存      1.txt.txt发生了ENTRY_MODIFY事件!
        3、删除“hello world!",并保存      1.txt.txt发生了ENTRY_MODIFY事件!
        4、新建2.txt文件    2.txt发生了ENTRY_CREATE事件!

        说明:编辑文件内容时,不算修改,保存时才算修改。

        5、新建文件夹“图片”
            新建文件夹发生了ENTRY_CREATE事件!
            新建文件夹发生了ENTRY_DELETE事件!
            图片发生了ENTRY_CREATE事件!
        OS执行过程:新建了一个名为“新建文件夹”的文件夹,再把此文件夹重命名为指定的名称。
        重命名时,”新建文件夹“消失了,算作删除,”图片“出现了,算作新建。

        6、在图片目录下,随便新建一个文件或者文件夹
            图片发生了ENTRY_MODIFY事件!
         说明监控的只是子文件、子文件夹,不会递归监控。

        7、全选,删除test下所有文件、子文件夹
            图片发生了ENTRY_DELETE事件!
            1.txt.txt发生了ENTRY_DELETE事件!
            2.txt发生了ENTRY_DELETE事件!
         */
    }


    public static Map<String, Map> readFiles(String dirPath, Map<String, Map> fileAndDirMap) {
        // 建立当前目录中文件的File对象
        File curfile = new File(dirPath);
        // 取得代表目录中所有文件的File对象数组
        File[] list = curfile.listFiles();
        if (list != null) {
            for (File file : list) {
                if (file.isDirectory()) {
                    //获取文件当前最近一次修改日期
                    long l = file.lastModified();
                    //以当前系统时间为准三十天前日期
                    Calendar theCa = Calendar. getInstance ();
                    theCa .setTime( new Date() );
                    theCa .add(Calendar.DATE, -30);
                    Date start = theCa .getTime();
                    long time = start.getTime();
                    if (l<time){
                        continue;
                    }

                    Map<String, Map> map = new HashMap<String, Map>();
                    fileAndDirMap.put(file.getPath(), map);
                    readFiles(file.getPath(), map);
                } else {
                    fileAndDirMap.put(file.getPath(), null);
                }
            }
        }
        // 遍历file数组
        return fileAndDirMap;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值