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 files_; // File -> Long
private List fileEntrys = new java.util.concurrent.CopyOnWriteArrayList();
private Collection> 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();
listeners_ = new ArrayList>();
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.
*
* 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> i = listeners_.iterator(); i.hasNext(); ) {
WeakReference 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));
}
/**
* Remove listener from this file monitor.
*
* @param fileListener Listener to remove.
*/
public void removeListener(FileListener fileListener) {
for (Iterator> i = listeners_.iterator(); i.hasNext(); ) {
WeakReference reference = (WeakReference) 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 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 files = new ArrayList(files_.keySet());
for (Iterator 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> j =
listeners_.iterator(); j.hasNext(); ) {
WeakReference reference =
(WeakReference) 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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2670046/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java實現ZooKeeper的zNode監控Java
- TiDB監控實現--存活監控TiDB
- Flume實時監控 單個追加檔案
- Java實現FTP跨伺服器檔案操作JavaFTP伺服器
- java web專案 使用elfinder 實現檔案管理器JavaWeb
- 檔案監控效能問題【BUG】
- Java實現檔案切割拼接Java
- linux 監控檔案內容變化Linux
- Vue SPA專案 + Sentry 實現前端錯誤監控Vue前端
- Java實現檔案下載功能Java
- vue/js實現檔案流下載,檔案下載進度監聽VueJS
- WPF 實現檔案/資料夾監聽工具
- nginx實現檔案伺服器Nginx伺服器
- 使用java的MultipartFile實現layui官網檔案上傳實現全部示例,java檔案上傳JavaUI
- Java實現檔案斷點續傳Java斷點
- Java檔案上傳如何實現呢?Java
- Prometheus+Grafana實現服務效能監控:windows主機監控、Spring Boot監控、Spring Cloud Alibaba Seata監控PrometheusGrafanaWindowsSpring BootCloud
- GO實現資料夾監控Go
- java中listFiles(Filefilter filter)檔案過濾器的實現過程JavaFilter過濾器
- Java 監控基礎 - 使用 JMX 監控和管理 Java 程式Java
- 前端監控進階篇 — Sentry 監控 Next.js 專案實踐前端JS
- pythonpyinotify監控檔案與目錄的變化Python
- 智慧檔案館網路監控運維策略運維
- 基於Prometheus閘道器的監控完整實現參考Prometheus
- PIGOSS BSM 如何實現伺服器硬體狀態監控?Go伺服器
- OpenTelemetry 實戰:gRPC 監控的實現原理RPC
- java 語音用xml檔案實現圖形介面 xml檔案JavaXML
- Java實現定時備份檔案教程Java
- Windows效能計數器監控實踐Windows
- JS實現監控微信小程式JS微信小程式
- linux監控資料夾內的檔案數量Linux
- Linux 使用 inotify 監控檔案或目錄變化Linux
- Sigar java 伺服器資訊探針、監控Java伺服器
- flutter使用dio實現 檔案下載並實現進度監聽總結Flutter
- 日誌監控實踐 - 監控Agent整合Lua引擎實現多維度日誌採集
- java實現檔案的下載的方法概述Java
- Arthas JVM 監控器JVM
- Docker容器的自動化監控實現Docker