Java_IO之RandomAccessFile原理详解及代码演示

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 等等)

看得开心记得点赞,爱你哦 ♥

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值