Java實(shí)現(xiàn)日志文件監(jiān)聽并讀取相關(guān)數(shù)據(jù)的方法實(shí)踐
項(xiàng)目需求
由于所在數(shù)據(jù)中臺(tái)項(xiàng)目組需要實(shí)現(xiàn)監(jiān)聽文件夾或者日志文件并讀取對(duì)應(yīng)格式的臟數(shù)據(jù)的需求,以便在文件、文件夾發(fā)生變化時(shí)進(jìn)行相應(yīng)的業(yè)務(wù)流程;所以在這里記錄下相關(guān)業(yè)務(wù)的實(shí)現(xiàn)及技術(shù)選型。
Apache Commons-IO
首先需要添加對(duì)應(yīng)依賴:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.7</version> </dependency>
版本可自行選擇,這里需要注意的是 2.7 版本及以上需要 Java 8
官網(wǎng)截圖:

Apache Commos IO中的 org.apache.commons.io.monitor包提供了文件系統(tǒng)監(jiān)聽的功能。

核心知識(shí)
- 一句話總結(jié):通過觀察者模式以及事件監(jiān)聽機(jī)制,以
FileAlterationObserver為核心,再通過FileAlterationListener,FileAlterationMonitor,就可以實(shí)現(xiàn)對(duì)文件系統(tǒng)的事件監(jiān)聽。 - 整體流程:
- 自定義文件監(jiān)聽類并繼承
FileAlterationListenerAdaptor實(shí)現(xiàn)對(duì)文件與目錄的創(chuàng)建,修改,刪除事件的處理 - 自定義文件監(jiān)控類,通過指定目錄創(chuàng)建一個(gè)觀察者
FileAlterationObserver - 向此監(jiān)視器添加文件系統(tǒng)觀察器,并添加文件監(jiān)聽器
- 通過
ApplicationRunner或者CommandLineRunner調(diào)用并執(zhí)行
代碼實(shí)現(xiàn)
- 文件監(jiān)聽類:
/**
* 文件監(jiān)聽類
* @author Greenarrow
* @date 2022-05-12 14:43
**/
public class FileListener extends FileAlterationListenerAdaptor {
private static Logger logger = LoggerFactory.getLogger(FileListener.class);
@Override
public void onStart(FileAlterationObserver observer) {
super.onStart(observer);
logger.info("onStart");
}
@Override
public void onDirectoryCreate(File directory) {
logger.info("[新建]:" + directory.getAbsolutePath());
}
@Override
public void onDirectoryChange(File directory) {
logger.info("[修改]:" + directory.getAbsolutePath());
}
@Override
public void onDirectoryDelete(File directory) {
logger.info("[刪除]:" + directory.getAbsolutePath());
}
@Override
public void onFileCreate(File file) {
String compressedPath = file.getAbsolutePath();
logger.info("[新建]:" + compressedPath);
List<String> contentList = null;
try {
if (file.canRead()){
// 將文件按行讀取為字符串集合
contentList = FileUtils.readLines(new File(compressedPath), StandardCharsets.UTF_8);
if (CollectionUtil.isNotEmpty(contentList)){
// 獲取對(duì)應(yīng)格式的數(shù)據(jù)并輸出,這里可自行添加業(yè)務(wù)處理
List<String> dirtyRecord = contentList.stream().filter(s -> s.startsWith("{") && s.endsWith("}")).collect(Collectors.toList());
dirtyRecord.forEach(System.out::println);
}
}
} catch (IOException e) {
e.printStackTrace();
logger.error("讀取文件內(nèi)容失敗",e);
}
}
@Override
public void onFileChange(File file) {
String compressedPath = file.getAbsolutePath();
logger.info("[修改]:" + compressedPath);
}
@Override
public void onFileDelete(File file) {
logger.info("[刪除]:" + file.getAbsolutePath());
}
@Override
public void onStop(FileAlterationObserver observer) {
super.onStop(observer);
logger.info("onStop");
}
}- 文件監(jiān)控類:
/**
* 文件監(jiān)聽測(cè)試 demo
* @author Greenarrow
* @date 2022-05-12 14:45
**/
public class FileMonitor {
FileAlterationMonitor monitor = null;
public FileMonitor(long interval) throws Exception {
monitor = new FileAlterationMonitor(interval);
}
/**
* 給文件添加監(jiān)聽
* @param path
* @param listener
*/
public void monitor(String path, FileAlterationListener listener) {
FileAlterationObserver observer = new FileAlterationObserver(new File(path));
monitor.addObserver(observer);
observer.addListener(listener);
}
public void stop() throws Exception {
monitor.stop();
}
public void start() throws Exception {
monitor.start();
}
}- 自定義 Runner 并實(shí)現(xiàn)
CommandLineRunner:
/**
* 項(xiàng)目啟動(dòng)之后開啟文件監(jiān)聽功能
* @author Greenarrow
* @date 2022-05-12 10:02
**/
@Component
// @Order(Integer.MIN_VALUE)
public class DirtyRecordRunner implements CommandLineRunner {
private static Logger logger = LoggerFactory.getLogger(DirtyRecordRunner.class);
@Value("${test}")
private String path;
@Override
public void run(String... args) throws Exception {
logger.info(this.getClass().getName()+"[開啟文件夾監(jiān)聽功能]");
FileMonitor fileMonitor = new FileMonitor(1000);
fileMonitor.monitor(path,new FileListener());
fileMonitor.start();
}
}總結(jié)
文件、文件夾監(jiān)聽功能較簡(jiǎn)單,實(shí)現(xiàn)方式可自行選擇
需要注意的是,通過 Runner 的方式在項(xiàng)目啟動(dòng)之后開啟相關(guān)監(jiān)聽功能,此方式存在缺陷,只能調(diào)用一次,出現(xiàn)異常就會(huì)停止,除非項(xiàng)目重啟,這里需要通過相關(guān)補(bǔ)償機(jī)制來實(shí)現(xiàn)
到此這篇關(guān)于Java實(shí)現(xiàn)日志文件監(jiān)聽并讀取相關(guān)數(shù)據(jù)的方法實(shí)踐的文章就介紹到這了,更多相關(guān)Java 日志文件監(jiān)聽讀取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flowable數(shù)據(jù)庫表分類及數(shù)據(jù)字典解析
這篇文章主要介紹了Flowable數(shù)據(jù)庫表分類及數(shù)據(jù)字典解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
基于SpringMVC實(shí)現(xiàn)網(wǎng)頁登錄攔截
SpringMVC的處理器攔截器類似于Servlet開發(fā)中的過濾器Filter,用于對(duì)處理器進(jìn)行預(yù)處理和后處理。因此,本文將為大家介紹如何通過SpringMVC實(shí)現(xiàn)網(wǎng)頁登錄攔截功能,需要的小伙伴可以了解一下2021-12-12
解析Linux系統(tǒng)中JVM內(nèi)存2GB上限的詳解
本篇文章是對(duì)Linux系統(tǒng)中JVM內(nèi)存2GB上限進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Java調(diào)用HTTPS接口實(shí)現(xiàn)繞過SSL認(rèn)證
SSL認(rèn)證是確保通信安全的重要手段,有的時(shí)候?yàn)榱朔奖阏{(diào)用,我們會(huì)繞過SSL認(rèn)證,這篇文章主要介紹了Java如何調(diào)用HTTPS接口實(shí)現(xiàn)繞過SSL認(rèn)證,需要的可以參考下2023-11-11
Java中的Gradle與Groovy的區(qū)別及存在的關(guān)系
這篇文章主要介紹了Java中的Gradle與Groovy的區(qū)別及存在的關(guān)系,Groovy是一種JVM語言,它可以編譯為與Java相同的字節(jié)碼,并且可以與Java類無縫地互操作,Gradle是Java項(xiàng)目中主要的構(gòu)建系統(tǒng)之一,下文關(guān)于兩者的詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-02-02
解讀nextLine().split(“[\\s]“)的意思
這篇文章主要介紹了解讀nextLine().split(“[\\s]“)的意思,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Java實(shí)現(xiàn)優(yōu)雅的參數(shù)校驗(yàn)方法詳解
這篇文章主要為大家詳細(xì)介紹了Java語言如何實(shí)現(xiàn)優(yōu)雅的參數(shù)校驗(yàn),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定是幫助,需要的可以參考一下2022-06-06
JAVA HTTP反向代理實(shí)現(xiàn)過程詳解
這篇文章主要介紹了JAVA HTTP反向代理實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06

