基于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
基于File NIO写的一个文件新增内容监控器的更多相关文章
- Windows cmd 将命令(/指令)写到一个文件里,直接运行这个文件。提高工作效率
Windows cmd 批处理(cmd/bat)文件的简单使用介绍 前言 如果你想我一样,要每天都需要在cmd上,用键盘去敲击相同的命令,时间一长,你就觉得很无聊.有没有什么比较高效的方法,让我们不用 ...
- java把一个文件的内容复制到另外一个文件
/** * java把一个文件的内容复制到另外一个文件 */import java.io.File;import java.io.FileInputStream;import java.io.File ...
- 你知道怎么从jar包里获取一个文件的内容吗
目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...
- AWK实现把一个文件根据内容进行分组输出多个文件
AWK实现把一个文件根据内容进行分组输出多个文件 1.首先准备文件data.txt(分隔符为tab) 第一列省编码,第二列省名称...... 2.将该大文件根据第一列的省编码进行分组并输出到各个省编码 ...
- 新建txt文件新增内容并打印出
#!/usr/bin/python import os file1=open("C:\Python34\ceshi.txt","a+"); #a+开一个文件用 ...
- 12小时包你学会基于ReactMix框架的ReactNativeApp开发(二)基于Css+HTML写第一个app页面
上一篇文章,大家对于ReactMix(https://github.com/xueduany/react-mix)框架有了一个基本认识,知道我们是一个语法糖,帮助大家基于一套代码,所有平台都能跑.那么 ...
- Python文件读写 - 读一个文件所有行,加工后写另一个文件
#Filename: file_read_and_write.py #打开文件,cNames读取所有行,储存在列表中,循环对每一行在起始处加上序号1,2,3,4 with open(r'file/co ...
- 基于Spring aop写的一个简单的耗时监控
前言:毕业后应该有一两年没有好好的更新博客了,回头看看自己这一年,似乎少了太多的沉淀了.让自己做一个爱分享的人,好的知识点拿出来和大家一起分享,一起学习. 背景: 在做项目的时候,大家肯定都遇到对一些 ...
- 关于ACtion类利用file类型取得上传文件的内容,名字和内容类型
上面的Action提供了两个属性:uploadFileName和uploadContentType,这个两个属性分别用于封转上传文件的文件名.上传文件的文件类型.Action类直接通过File类型属性 ...
随机推荐
- LGP3790题解
建议改为 省 选 原 题 题意:求所有生成树的边权 \(\gcd\) 之和. 看到 \(\gcd\) 立刻想反演. \[\sum_T\gcd_{e \in T}e_v \] 这里设 \(E=e_v(e ...
- 关于C#窗体应用程序的一点总结
1.在窗体Form在Form_Load函数中写了过多的界面初始化语句导致界面卡顿时 解决方法为:将一些初始化语句写在public Form()函数中,会大大加快程序的初始化加载速度. 2.为butto ...
- ArcMap操作随记(10)
1.基于点生成辐射线 [缓冲区]→[构造视线] 2.求算点集中于剩余点距离总和最小的点 [构造视线]→[计算几何]→[汇总] 3.关于空间参考,关于投影 ①横轴墨卡托投影 "等角横轴切圆柱投 ...
- emu8086 调用LED面板的方法
一.实验要求 1.熟悉并掌握 EMU8086 汇编语言调试环境: 2.学习 8086 的指令系统,输入简单的指令,观察各寄存器.内存相关单元以及处理器标志位的变化(所有数据传送类指令,可参考教材用例) ...
- Anaconda 01_安装问题
一. 创建环境 1.打开cmd 使用如下语句创建环境 conda create -n 环境名 2. 查看当前conda所有环境 conda info --envs 3.激活环境(其中一句) Co ...
- Spring——初识
1.1 使用 导包:Spring Web MVC(maven) <!-- https://mvnrepository.com/artifact/org.springframework/sprin ...
- 字符串的高级应用-char a[100] = "1+2=;3-2=;2*5=;8/4=;" 得到char a[100] ="1+2=3;3-2=1;2*5=10;8/4=2;"
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char a[100] = "1+2=;3 ...
- 什么?Android上面跑Linux?
前言 众所周知,现在程序员因为工作.个人兴趣等对各种系统的需求越来越大,部分人电脑做的还是双系统.其中,比较常见的有各种模拟器.虚拟机在windows上面跑Android.Linux,大家估计都习以为 ...
- 平衡树:为什么Redis内部实现用跳跃表
摘要:Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一. 本文分享自华为云社区<5分钟了解Redis的内部实现跳跃表(skiplist)>,作者:万猫学社. ...
- 『忘了再学』Shell基础 — 4、Bash基本功能(history命令)
目录 1.history历史命令 2.设置命令历史记录的条数 3.清空历史命令 4.历史命令的调用 5.命令与文件的补全 在Linux系统中默认的Shell就是Bourne-AgainShell(简称 ...