這篇文章將為大家詳細(xì)講解有關(guān)Java中怎么實(shí)現(xiàn)一個(gè)FileMonitor文件監(jiān)控器,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)安福免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
應(yīng)用場(chǎng)景:
代碼可以實(shí)現(xiàn)文件變化后的監(jiān)聽(tīng),如文件變化,自動(dòng)重新加載文件內(nèi)容,實(shí)現(xiàn)配置文件的熱部署。
代碼:
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 * 文件監(jiān)控器 * * @author yx * @date 2019/12/21 0:59 */public class FileMonitor { /** * 每2秒更新的默認(rèn)監(jiān)控器 */ 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); } } /** * 添加監(jiān)控文件實(shí)體。 * * @param fileEntry */ public void addFileEntry(FileEntry fileEntry) { if (!fileEntrys.contains(fileEntry)) { fileEntrys.add(fileEntry); } } /** * 通過(guò)文件實(shí)體的標(biāo)識(shí)判斷監(jiān)控文件實(shí)體是否存在。 * * @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; } /** * 通過(guò)文件實(shí)體標(biāo)識(shí)刪除一個(gè)監(jiān)控文件實(shí)體。 * * @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("執(zhí)行文件監(jiān)控發(fā)生錯(cuò)誤:" + 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("執(zhí)行文件監(jiān)控發(fā)生錯(cuò)誤" + 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,那么當(dāng)文件發(fā)生變動(dòng)時(shí)只觸發(fā)指定的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; /** * 構(gòu)造函數(shù)。 * * @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); } /** * 構(gòu)造函數(shù)。 * * @param id 標(biāo)識(shí) * @param file 要監(jiān)控的文件 * @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) { //監(jiān)控對(duì)象已經(jīng)不存在,請(qǐng)求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("執(zhí)行文件監(jiān)控事件監(jiān)聽(tīng)" + 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";// 文件監(jiān)控FileListener fileListener = new FileListener() {@Overridepublic void fileChanged(FileEntry fileEntry) {// TODO 文件變化后的業(yè)務(wù)處理}};File file = new File(fileName);FileEntry fileEntry = new FileEntry("database", file);// 設(shè)置文件監(jiān)控fileEntry.setFileListener(fileListener);FileMonitor.getDefaultFileMonitor().addFileEntry(fileEntry);
關(guān)于Java中怎么實(shí)現(xiàn)一個(gè)FileMonitor文件監(jiān)控器就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
本文標(biāo)題:Java中怎么實(shí)現(xiàn)一個(gè)FileMonitor文件監(jiān)控器
本文鏈接:http://muchs.cn/article18/gddsdp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、商城網(wǎng)站、ChatGPT、外貿(mào)網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
全網(wǎng)營(yíng)銷(xiāo)推廣知識(shí)