JAVA 监控并获取日志类文件变化(新增)
使用 JDK7+(1.7之前没有的哈!?) 工具类 java.nio.file.WatchService
写来用于监控日志文件新增内容(只能检测获取新增内容哈!?中间改一手读不出来的哈!)
要配置目录和文件哈!
源码:
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
/**
* 监控文件变化
* @author YL
**/
public class FileWatcher {
public static void main(String[] args) throws IOException, InterruptedException {
// 监控的目录
String filePath = "C:\\project\\imony_abroad\\logs\\";
// 要监控的文件
String fileName = "spring.log";
FileWatcher.watcherLog(filePath, fileName, System.out::println);
}
/**
* 文件监控
* 同步调用会阻塞
* @param filePath
* @param fileName
* @param consumer
* @throws IOException
* @throws InterruptedException
*/
public static void watcherLog(String filePath, String fileName, Consumer<String> consumer) throws IOException, InterruptedException {
WatchService watchService = FileSystems.getDefault().newWatchService();
Paths.get(filePath).register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
// 文件读取行数
AtomicLong lastPointer = new AtomicLong(0L);
do {
WatchKey key = watchService.take();
List<WatchEvent<?>> watchEvents = key.pollEvents();
watchEvents.stream().filter(
i -> StandardWatchEventKinds.ENTRY_MODIFY == i.kind()
&& fileName.equals(((Path) i.context()).getFileName().toString())
).forEach(i -> {
if (i.count() > 1) {
// "重复事件"
return;
}
File configFile = Paths.get(filePath + "/" + i.context()).toFile();
StringBuilder str = new StringBuilder();
// 读取文件
lastPointer.set(getFileContent(configFile, lastPointer.get(), str));
if (str.length() != 0 ) {
consumer.accept(str.toString());
}
});
key.reset();
} while (true);
}
/**
* beginPointer > configFile 时会从头读取
* @param configFile
* @param beginPointer
* @param str 内容会拼接进去
* @return 读到了多少字节, -1 读取失败
*/
private static long getFileContent(File configFile, long beginPointer, StringBuilder str) {
if (beginPointer < 0) {
beginPointer = 0;
}
RandomAccessFile file = null;
boolean top = true;
try {
file = new RandomAccessFile(configFile, "r");
if (beginPointer > file.length()) {
return 0;
}
file.seek(beginPointer);
String line;
while ((line = file.readLine()) != null) {
if (top) {
top = false;
} else {
str.append("\n");
}
str.append(new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
}
return file.getFilePointer();
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}