基于File NIO写的一个文件新增内容监控器
基于File NIO写的一个文件新增内容监控器
需求说明
监控一个文件,如果文件有新增内容,则在控制台打印出新增内容.
代码示例
FileMoniter文件监控器类
package com.black.basic.io.bytestreams;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* 文件监控器,如果文件有新增内容,则输出文件新增内容
*
* @author black
* @date 2022-01-19 12:04:016
*/
public class FileMoniter {
public static void main(String[] args) {
FileMoniter moniter = new FileMoniter();
// 获取工程里文件
ClassLoader classLoader = moniter.getClass().getClassLoader();
String fileName = classLoader.getResource("com/black/basic/io/test_file_en.txt").getFile();
// 开始监控文件
moniter.moniter(fileName);
}
// 监控文件
public void moniter(String fileName) {
File file = new File(fileName);
// 判断文件是否可读,如果可读,进行扫描;反之,不做处理
if (checkRead(file)) {
// 文件可读,开始扫描文件,输出文件新增内容
scan(file);
} else {
System.out.println("文件无法读取!");
}
}
// 是否可读
public boolean checkRead(File file) {
return file.exists() & file.canWrite();
}
public void scan(File file) {
// 文件读取位置
long curPosition = 0;
// 文件大小
long size = -1;
// 文件最后修改日期
long lastModifiedTime = 0L;
while (true) {
sleep();
// 判断文件是否修改
if (lastModifiedTime == file.lastModified()) {
// 没有修改则跳过此次处理.
continue;
} else {
// 更新当前修改时间
lastModifiedTime = file.lastModified();
}
try (FileChannel fc = new FileInputStream(file).getChannel();) {
// 判断有无新增内容
long fcSize = fc.size();
if (size == fcSize) {
// 没有新增内容则跳过此次处理.
continue;
} else {
size = fcSize;
}
// 判断当前文件读取位置
if (curPosition != 0) {
fc.position(curPosition);
}
// 分配 1024 字节的buffer
ByteBuffer bf = ByteBuffer.allocate(1024);
int c;
// 读取文件内容到 buffer,返回读取字节数c
while ((c = fc.read(bf)) > 0) {
// limit=positon,position =0
bf.flip();
byte[] b = new byte[c];
// 读取buffer中的内容到字节数组 b
bf.get(b);
// 打印 b
System.out.print(new String(b));
// 清除 buffer 为下次读取准备
bf.clear();
// 更新当前文件读取位置
curPosition = fc.position();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 暂停 1秒
public void sleep() {
try {
TimeUnit.SECONDS.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
本地工程的com.black.basic.io
包下test_file_en.txt文件内容:
# test file encoding UTF-8
name age