温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中怎么实现一个FileMonitor文件监控器

发布时间:2021-08-07 11:53:44 来源:亿速云 阅读:114 作者:Leah 栏目:编程语言

这篇文章将为大家详细讲解有关Java中怎么实现一个FileMonitor文件监控器,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

应用场景:

代码可以实现文件变化后的监听,如文件变化,自动重新加载文件内容,实现配置文件的热部署。

代码:

package com.yx.demo.filemonitor; import java.io.File;import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Timer;import java.util.TimerTask; /** * FileMonitor * 文件监控器 * * @author yx * @date 2019/12/21 0:59 */public class FileMonitor {   /**   * 每2秒更新的默认监控器   */  private static FileMonitor defaultFileMonitor = new FileMonitor(2 * 1000);   private Timer timer_;  private HashMap<File, FileEntry> files_; // File -> Long  private List<FileEntry> fileEntrys = new java.util.concurrent.CopyOnWriteArrayList<FileEntry>();  private Collection<WeakReference<FileListener>> listeners_; // of WeakReference(FileListener)   private long pollingInterval = 10000;   public static FileMonitor getDefaultFileMonitor() {    return defaultFileMonitor;  }   /**   * Create a file monitor instance with specified polling interval.   *   * @param pollingInterval Polling interval in milli seconds.   */  public FileMonitor(long pollingInterval) {    this.pollingInterval = pollingInterval;     files_ = new HashMap<File, FileEntry>();    listeners_ = new ArrayList<WeakReference<FileListener>>();     timer_ = new Timer("FileMonitor", true);    timer_.schedule(new FileMonitorNotifier(), 0, pollingInterval);  }   /**   * Stop the file monitor polling.   */  public void stop() {    timer_.cancel();    timer_ = null;  }   public void start() {    if (timer_ == null) {      timer_ = new Timer(true);      timer_.schedule(new FileMonitorNotifier(), 0, pollingInterval);    }  }   /**   * Add file to listen for. File may be any java.io.File (including a   * directory) and may well be a non-existing file in the case where the   * creating of the file is to be trepped.   * <p>   * More than one file can be listened for. When the specified file is   * created, modified or deleted, listeners are notified.   *   * @param file File to listen for.   */  public void addFile(String id, File file) {    if (!files_.containsKey(file)) {       FileEntry entry = new FileEntry(id, file, file.exists() ? file.lastModified() : -1);      files_.put(file, entry);    }  }   /**   * 添加监控文件实体。   *   * @param fileEntry   */  public void addFileEntry(FileEntry fileEntry) {    if (!fileEntrys.contains(fileEntry)) {      fileEntrys.add(fileEntry);    }  }   /**   * 通过文件实体的标识判断监控文件实体是否存在。   *   * @param id   * @return   */  public boolean fileEntryExists(String id) {    if (id == null) {      return false;    }     for (int i = 0; i < fileEntrys.size(); i++) {      if (id.equals(fileEntrys.get(i).getId())) {        return true;      }    }     return false;  }   /**   * 通过文件实体标识删除一个监控文件实体。   *   * @param id   */  public void removeFileEntry(String id) {    if (id == null) {      return;    }     for (int i = 0; i < fileEntrys.size(); i++) {      if (id.equals(fileEntrys.get(i).getId())) {        fileEntrys.remove(i);        return;      }    }  }   /**   * Remove specified file for listening.   *   * @param file File to remove.   */  public void removeFile(File file) {    files_.remove(file);  }   /**   * Add listener to this file monitor.   *   * @param fileListener Listener to add.   */  public void addListener(FileListener fileListener) {    // Don't add if its already there    for (Iterator<WeakReference<FileListener>> i = listeners_.iterator(); i.hasNext(); ) {      WeakReference<FileListener> reference = i.next();      FileListener listener = (FileListener) reference.get();      if (listener == fileListener) {        return;      }    }     // Use WeakReference to avoid memory leak if this becomes the    // sole reference to the object.    listeners_.add(new WeakReference<FileListener>(fileListener));  }   /**   * Remove listener from this file monitor.   *   * @param fileListener Listener to remove.   */  public void removeListener(FileListener fileListener) {    for (Iterator<WeakReference<FileListener>> i = listeners_.iterator(); i.hasNext(); ) {      WeakReference<FileListener> reference = (WeakReference<FileListener>) i.next();      FileListener listener = (FileListener) reference.get();      if (listener == fileListener) {        i.remove();        break;      }    }  }   /**   * This is the timer thread which is executed every n milliseconds according   * to the setting of the file monitor. It investigates the file in question   * and notify listeners if changed.   */  private class FileMonitorNotifier extends TimerTask {    @Override    public void run() {      try {        for (Iterator<FileEntry> i = fileEntrys.iterator(); i.hasNext(); ) {          try {            FileEntry entry = i.next();            if (entry == null || !entry.check()) {              i.remove();            }          } catch (Throwable t) {            t.printStackTrace();            System.out.println("执行文件监控发生错误:" + t.getMessage());          }        }         // Loop over the registered files and see which have changed.        // Use a copy of the list in case listener wants to alter the        // list within its fileChanged method.        Collection<File> files = new ArrayList<File>(files_.keySet());         for (Iterator<File> i = files.iterator(); i.hasNext(); ) {          File file = i.next();          try {            FileEntry fileEntry = files_.get(file);            long lastModifiedTime = fileEntry.getLastModified();            long newModifiedTime = file.exists() ? file.lastModified() : -1;             //logger.debug(file.getAbsolutePath());            //logger.debug("  {}=>{}", lastModifiedTime, newModifiedTime);            // Chek if file has changed            if (newModifiedTime != lastModifiedTime) {              //logger.debug("file changed {})", file.getAbsolutePath());              fileEntry.setLastModified(newModifiedTime);              // Register new modified time              files_.put(file, fileEntry);               if (fileEntry.getFileListener() != null) {                fileEntry.getFileListener().fileChanged(fileEntry);              } else {                // Notify listeners                for (Iterator<WeakReference<FileListener>> j =                    listeners_.iterator(); j.hasNext(); ) {                  WeakReference<FileListener> reference =                      (WeakReference<FileListener>) j.next();                  FileListener listener = (FileListener) reference.get();                   // Remove from list if the back-end object has been GC'd                  if (listener == null) {                    j.remove();                  } else {                    listener.fileChanged(fileEntry);                  }                }              }            }          } catch (Throwable t) {            if (file != null) {              t.printStackTrace();              System.out.println(                  "file monitor execute error, file=" + file.getAbsolutePath() +                      t.getMessage());            } else {              System.out.println(                  "file monitor execute error, file=null" + t.getMessage());            }          }        }      } catch (Throwable t) {        System.out.println("执行文件监控发生错误" + t.getMessage());      }    }  }}package com.yx.demo.filemonitor; /** * FileListener * * @author yx * @date 2019/12/21 0:55 */public interface FileListener { /** *  * @param fileEntry */ public void fileChanged(FileEntry fileEntry);}

package com.yx.demo.filemonitor;

import java.io.File;import java.lang.ref.WeakReference;/** * FileEntry * 文件Entry,如果FileEntry指定了FileListener,那么当文件发生变动时只触发指定的FileListener * * @author yx * @date 2019/12/21 0:56 */public class FileEntry {  String id;  File file;  long lastModified;  FileListener fileListener = null;  Object userData;  WeakReference<Object> reference = null;  /**   * 构造函数。   *   * @param id   * @param file   */  public FileEntry(String id, File file) {    this(id, file, file.exists() ? file.lastModified() : -1);  }  public FileEntry(Object reference, String id, File file) {    this(id, file, file.exists() ? file.lastModified() : -1);    reference = new WeakReference<Object>(reference);  }  /**   * 构造函数。   *   * @param id      标识   * @param file     要监控的文件   * @param lastmodified 最后修改日期   */  public FileEntry(String id, File file, long lastmodified) {    super();    this.id = id;    this.file = file;    this.lastModified = lastmodified;  }  public boolean check() {    if (reference != null && reference.get() == null) {      //监控对象已经不存在,请求FileMonitor删除自己      return false;    }    long newModifiedTime = file.exists() ? file.lastModified() : -1;    if (lastModified != newModifiedTime) {      this.lastModified = newModifiedTime;      FileListener ls = this.getFileListener();      if (ls == null) {        return false;      } else {        try {          ls.fileChanged(this);        } catch (Exception e) {          e.printStackTrace();          System.err.println("执行文件监控事件监听" + e.getMessage());        }        return true;      }    } else {      return true;    }  }  public String getId() {    return id;  }  public void setId(String id) {    this.id = id;  }  public File getFile() {    return file;  }  public void setFile(File file) {    this.file = file;  }  public long getLastModified() {    return lastModified;  }  public void setLastModified(long lastModified) {    this.lastModified = lastModified;  }  public FileListener getFileListener() {    return fileListener;  }  public void setFileListener(FileListener fileListener) {    this.fileListener = fileListener;  }  public Object getUserData() {    return userData;  }  public void setUserData(Object userData) {    this.userData = userData;  }}

使用demo:

// 文件路径String fileName = "conf/database.xml";// 文件监控FileListener fileListener = new FileListener() {@Overridepublic void fileChanged(FileEntry fileEntry) {// TODO 文件变化后的业务处理}};File file = new File(fileName);FileEntry fileEntry = new FileEntry("database", file);// 设置文件监控fileEntry.setFileListener(fileListener);FileMonitor.getDefaultFileMonitor().addFileEntry(fileEntry);

关于Java中怎么实现一个FileMonitor文件监控器就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI