你的位置:首页 > Java教程

[Java教程]Jnotify动态监听文件夹,邮件系统文件夹监听示例


JNotify,一个支持动态监控文件和文件夹(支持级联监控)的架包。在linux系统中,调用的是linux底层的inotify服务,只是添加了对子文件夹级联监控的功能。在windows中,需要添加附件的dll文件,因为windows默认没有该服务

一、邮件系统对本地文件夹的监听

1、使用 jnotify 需要导入 jnotify.jar

2、需要在jdk/bin 添加jnotify 本地方法:jnotify.dll  jnotify_64bit.dll

二、步骤

1、jnotify监听目录

public class MailWatcher {
    /** 日志 */
    private static final Logger LOG = LoggerFactory
            .getLogger(MailWatcher.class);
    // 收件路径
    private String path;
    public MailWatcher() {
        // 收件邮件路径
         path = Configure.getString("path");
    }
    // 监听主线程
    public void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED
                            | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
                    // 监听接收邮件
                    int watchId = JNotify.addWatch(path, mask, true, new  MailListener());
                    // 是否监听子目录
                    boolean watchSubtree = true;
                    // 日志
                    LOG.info("watcher开始监听:{} {}", path, watchId);
                } catch (Exception e) {
                    LOG.error("监听失败", e);
                }
            }
        }).start();


        // 不让主线程挂掉
        while (true) {
            try {
                Thread.sleep(200);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

2、监听器,

//文件创建 动态监听
public class MailListener implements JNotifyListener {

    /** 日志 */
    private static final Logger LOG = LoggerFactory.getLogger(MailListener.class);
//文件重命名时
    public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
        LOG.debug("{} renamed to {}", oldName, newName);
    }
//文件修改时
    public void fileModified(int wd, String rootPath, String name) {
        LOG.debug("{} modified", name);
    }
//文件删除时
    public void fileDeleted(int wd, String rootPath, String name) {
        LOG.debug("{} deleted", name);
    }
//文件创建时
    public void fileCreated(final int wd, final String rootPath, final String name) {
        if (name.endsWith(".eml")) {
            LOG.info("{} created", name);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    LOG.info("{},开始读取", name);
                    MimeMessage msg = null;
                    File file = new File(rootPath, name);
                    try {
                        Thread.sleep(Configure.getLong("wait_first_time"));
                    } catch (Exception e) {
                        LOG.warn("{},初始等待失败", name);
                    }
                    // 再循环等待50次,每次等待10秒,共计500秒
                    // 写入邮件需要时间,所以循环
                    for (int i = 0; i < Configure.getInt("wait_times"); i++) {
                        try {

          //这里写的封装,file--->mimemessage
                            msg = EmlFileHelper.getMimeFile(file);
                            break;
                        } catch (Exception e) {
                            LOG.debug("第{}次读取文件{}失败", i + 1, name, e);
                        }
                        try {
                            Thread.sleep(Configure.getLong("wait_time_interval") * 1000l);
                        } catch (InterruptedException e) {
                            LOG.debug("等待失败", e);
                        }
                    }
                    if (msg == null) {
                        LOG.error("{},重试后读取失败", name);
                        return;
                    }
                    if (!Configure.getBoolean("not_intercept_send_email")) {
                        // 判断是否是发出的邮件,如果是,就不记录
                        try {
                            String receiver = name.substring(0, name.indexOf(File.separator));

          //这里是我写的邮件帮助类,忽略
                            String from = MailHelper.getFrom(msg);
                            if (from.startsWith(receiver + "@")) {
                                LOG.info("{}是发出的邮件,不记录", name);
                                return;
                            }
                        } catch (Exception e) {
                            LOG.error("判断是否是发出的邮件失败", e);
                        }
                    }
                    try {
                        saveMsg(msg, name);
                        LOG.info("{},保存成功", name);
                    } catch (Exception e) {
                        LOG.error("{},保存失败", name, e);
                    }
                }
            }).start();
        }       
    }
}


3、开启监听,

public class Main {
    public static void main(String[] args) throws Exception {
        new MailWatcher().start();
    }
}

4、说明,在main中开启主线程,文件修改触发jnotify 监听方法,