監聽的文件變化的方式有很多,但是比較完美的還是jNotify https://jnotify.sourceforge.net/ 對比一下監控方式的優缺點 | 方式 | 缺點 | | | | |java原生watch | 可能對文件時間獲取有缺毫秒的問題 | |commons-io | 沒有文件重命名 ...
監聽的文件變化的方式有很多,但是比較完美的還是jNotify
https://jnotify.sourceforge.net/
對比一下監控方式的優缺點
方式 | 缺點 |
---|---|
java原生watch | 可能對文件時間獲取有缺毫秒的問題 |
commons-io | 沒有文件重命名事件的監聽實現 |
jNotify | 配置複雜,需要添加dll/so文件到系統 |
具體的jnotfiy的配置可自行查找。
現在給出jnotify的具體實現
- 導入依賴
<!-- https://mvnrepository.com/artifact/net.contentobjects.jnotify/jnotify -->
<dependency>
<groupId>net.contentobjects.jnotify</groupId>
<artifactId>jnotify</artifactId>
<version>0.94</version>
</dependency>
- 編寫監控代碼
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyAdapter;
import net.contentobjects.jnotify.JNotifyException;
import java.io.File;
public class Watch extends JNotifyAdapter {
//可以寫到配置文件中
private static String WATCH_BASE_PATH;
public Watch(String path){
Watch.WATCH_BASE_PATH = path;
}
/**
* 關註目錄的事件
*/
int mask =JNotify.FILE_CREATED |JNotify.FILE_DELETED| JNotify.FILE_RENAMED| JNotify.FILE_MODIFIED;
/**
* 是否監視子目錄,即級聯監視
*/
boolean watchSubtree = true;
/**
* 監聽程式Id
*/
public int watchID;
/**
* 容器啟動時啟動監視程式
*/
public void beginWatch() {
/**
* 添加到監視隊列中
*/
try {
this.watchID = JNotify.addWatch(WATCH_BASE_PATH, mask, watchSubtree, this);
System.err.println("jnotify -----------啟動成功-----------:" + watchID );
} catch (JNotifyException e) {
e.printStackTrace();
}
/**
* 死迴圈,線程一直執行,休眠一分鐘後繼續執行,主要是為了讓主線程一直執行 休眠時間和監測文件發生的效率無
* (就是說不是監視目錄文件改變一分鐘後才監測到,監測幾乎是實時的,調用本地系統庫)
*/
while (true) {
try {
//主要緩和主線程的執行效率,
Thread.sleep(600);
} catch (InterruptedException e) {
// ignore it
}
}
}
/**
* 文件創建
* @param wd 監聽程式Id 初始為1,多個監控程式以此加1
* @param rootPath 目錄名
* @param name 文件名
*/
@Override
public void fileCreated(int wd, String rootPath, String name) {
System.err.println(wd+"----->文件被創建, 創建位置為: " + rootPath + "\\" + name);
}
/**
* 刪除文件
* @param wd 監聽程式Id 初始為1,多個監控程式以此加1
* @param rootPath 目錄名
* @param name 文件名
*/
@Override
public void fileDeleted(int wd, String rootPath, String name) {
System.err.println(wd+"----->文件被刪除, 被刪除的文件名為:" + rootPath + name);
}
/**
* 文件修改 (文件內容被修改和文件夾被修改都可以檢測到)
* @param wd 監聽程式Id 初始為1,多個監控程式以此加1
* @param rootPath 目錄名
* @param name 文件名
*/
@Override
public void fileModified(int wd, String rootPath, String name) {
String filePath = rootPath + name;
boolean isDir = filePath.indexOf('.') < 1;
// 是目錄變更
if(filePath.indexOf('.') < 1){
return;
}
System.err.println(wd+"----->文件內容被修改, 文件名為:" + rootPath + "\\" + name + ", isdir:" + isDir);
}
/**
* 文件重命名
* @param wd 監聽程式Id 初始為1,多個監控程式以此加1
* @param rootPath 目錄名
* @param oldName 修改前目錄名
* @param newName 修改後目錄名
*/
@Override
public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
String filePath = rootPath + oldName;
// 是目錄變更
if(filePath.indexOf('.') < 1){
System.err.println(wd+"----->文件夾被重命名, 原文件名為:" + rootPath + "\\" + oldName
+ ", 現文件名為:" + rootPath + "\\" + newName);
} else {
System.err.println(wd+"----->文件被重命名, 原文件名為:" + rootPath + "\\" + oldName
+ ", 現文件名為:" + rootPath + "\\" + newName);
}
}
}
- 查看輸出