RandomAccessFile学习
RandomAccessFile类中几个特色方法的使用 以及 模拟实现简单的Log读取和记录偏移量
RandomAccessFile是java.io包下比较特殊的一个文件内容随机读写类,与OutputStream write等不同之处就是,它可以实现随机位置读写,且自带指针偏移量标识
注意:RandomAccessFile只适用于读写文件,并不能读写其他IO节点
一、RandomAccessFile 特点
1.支持随机访问读写
2.自带指针标识,方便记录读写位置
3.适用于文件IO操作
具体方法如下图:
构造方法参数 : File文件对象/String文件路径 , String类型mode
四种mode :
"r" : 只读模式,不能写操作
"rw" : 读写模式
"rws" : 读写模式,每次写操作,同步的刷新到磁盘,刷新内容和元数据
"rwd" : 读写模式,每次写操作,同步的刷新到磁盘,刷新内容
注 - 与其他IO流相比,较特殊的方法 :
long getFilePointer( ):返回文件记录指针的当前位置
void seek(long pos ):将文件指针定位到pos位置
long length() 获取文件长度long
本类实现的随机读写也正是依赖于这几个特殊的方法
二、适用场景
1.适用于指定位置读取文件数据
注意 :
需要指定读取偏移量,seek(long pos)方法跳过偏移量,从指定位置后边开始读数据
2.适用于文件末尾追加写入/指定位置写入数据
注意 :
文件末尾追加,先获取文件长度,seek方法跳过文件长
指定位置写入:seek方法使光标指针跳跃到指定位置,光标指针后到文件结尾的数据缓存到临时文件(否则写入会被覆盖)
然后写入新数据,再次追加结尾部分的临时数据
3.大文件多线程读取下载
注意 :
注意三种判断条件:
过度读取 : 读取总长度>需要下载的文件长度,停止读取
少量读取 : 读取总长度<需要下载的文件长度,继续正常读取
下载完成 : 停止读取
代码演示:模拟实现简单的Log读取并记录偏移量
Log.txt手动写入数据,程序不断读取并记录偏移量到offset.txt文件中,每次只读最新日志数据,不会重复读取
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.RandomAccessFile;
/**
* Created with IntelliJ IDEA
*
* @Author Big_moo
* @Date 2022/02/12/16:39
* @Descript
* java.io.RandomAccessFile简单演示
* 实现简单的Log读取和偏移量记录
*/
public class RandomAccessFileTest {
//模拟Log日志文件
private static final String logFile = "C:\\Users\\ZenBook\\Desktop\\Test\\Log.txt";
//记录偏移量文件
private static final String offsetFile = "C:\\Users\\ZenBook\\Desktop\\Test\\offset.txt";
//randomAccessFile可选模式
private static final String[] models = {"r","rw","rws","rwd"};
public static void main(String[] args) throws Exception {
//构建RandomAccessFile对象
RandomAccessFile rafLog = new RandomAccessFile(logFile,models[0]);
//初始偏移量 首次读取偏移量默认为0
long offset = 0;
//调用工具类读取偏移量文件
String offsetStr = FileUtils.readFileToString(new File(offsetFile));
//定位确定偏移量
if(offsetStr!=null && !"".equals(offsetStr)){
offset = Long.parseLong(offsetStr);
}
//跳过偏移量长度
rafLog.seek(offset);
//循环读取最新Log日志 没有最新日志程序进入睡眠状态
while(true){
//读取一行日志文件
String line = rafLog.readLine();
if(line!=null){
//指定字符集 防止中文乱码
line = new String(line.getBytes("iso_8859_1"));
//Log数据处理(我这里直接输出到控制台)
System.out.println(line);
//获取当前指针位置
long filePointer = rafLog.getFilePointer();
//更新覆盖写入偏移量
offset+=filePointer;
FileUtils.writeStringToFile(new File(offsetFile),String.valueOf(offset));
}else{
Thread.sleep(2000);
}
}
}
}
这里我引用了一个文件工具类FileUtils,方便偏移量的记录
使用FeilUtils工具类需要在pom文件中引入依赖:
<!--文件读取工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
在apache的的常用包commons-io.jar中,有对文件处理的工具类FileUtils,了解这个类的使用,在开发中可以快速完成对文件的一些功能的处理,简单介绍几个,有兴趣的朋友可以深入研究一下
//文件1
File file1;
//文件2
File file2;
//复制文件 copy one file into another
FileUtils.copyFile(file1, file2);
//读取文件内容为字符串
String str = FileUtils.readFileToString(file1);
//把文件内容转换为字符串集合,每行一个字符串对象,也可以readline()单行读取
List<String> res = FileUtils.readLines(file1);
//获取目录下或者子目录下的文件,文件类型可以指定
Collection<File> res = FileUtils.listFiles(file1, { "xml", "txt" }, true);
//复制目录
FileUtils.copyDirectoryToDirectory(file1, file2);
//删除目录
FileUtils.deleteDirectory(file1);
总结
RandomAccessFile类的存在可以方便我们实现很多业务,例如:
大型日志类文件快速定位获取数据
多线程并发读写
更加方便的获取二进制文件(自带读写转码方法 readDouble writeLong 等等)
看得开心记得点赞,爱你哦 ♥