RandomAccessFile简介与使用

RandomAccessFile简介与使用今儿翻阅 jdk 源码的时候 无意间发现了 RandomAccess 这个类 从来没见过 也没使用过 带着好奇心 我决定深入了解一下这个类的意义和使用方法 从字面意思来看这个 随机通行文件其实个人感觉就是 一款功能较丰富的文本编辑 api 翻阅类的注释可以看出 这是一个增强版的文本处理类 曾经的我们如何处理文本以前我们要处理一个文件会怎么做 是不是如下图所示 上面是

今儿翻阅jdk源码的时候,无意间发现了RandomAccessFile这个类,从来没见过,也没使用过,带着好奇心,我决定深入了解一下这个类的意义和使用方法。

从字面意思来看这个:随机 通行 文件

其实个人感觉就是:

一款功能较丰富的文本编辑工具

话不多说,让我们先一探究竟,初步了解这个类的设计理念

目录

一、api的研究

曾经的我们如何处理文本

RandomAccessFile类帮我们处理文本

二、实际操作一下吧

三、对该工具类的价值分析


一、api的研究

曾经的我们如何处理文本

以前我们要处理一个文件会怎么做?是不是如下图所示:

RandomAccessFile简介与使用

上面是读取文件的方式,写文件也一样,我们需要使用输出流,如下图所示:

RandomAccessFile简介与使用

ok 看到这里想必大家都会发现,我对一个文件的读写操作需要new两个类,分别是读流和写流,并且他们的方法并不多

RandomAccessFile类帮我们处理文本

首先观察构造器:

RandomAccessFile简介与使用

可以发现这里定义了四种模式:R RW RWD RWS

r 以只读的方式打开文本,也就意味着不能用write来操作文件
rw 读操作和写操作都是允许的
rws 每当进行写操作,同步的刷新到磁盘,刷新内容和元数据
rwd 每当进行写操作,同步的刷新到磁盘,刷新内容

下面让我们看看RandomAccessFile为我们提供的方法:

RandomAccessFile简介与使用

可以看出:

这个类集中了丰富的读写方法

下面我举几个比较典型的方法来说明一下这个类的强大之处

============================================

1、seek:指定文件的光标位置,通俗点说就是指定你的光标位置

然后下次读文件数据的时候从该位置读取。

============================================

2、getFilePointer:我们注意到这是一个long类型的返回值,

字面意思就是返回当前的文件光标位置。

这样方便我们后面读取插入。

============================================

3、length:毫无疑问的方法,文件的长度,返回long类型。

注意它并不会受光标的影响。只会反应客观的文本长度。

============================================

4、read()、read(byte[] b)、read(byte[] b,int off,int len)

这些方法跟readstream中的方法一样,

例如最后一个:定义缓冲数组,从数组的off偏移量位置开始写,

读取转换为数组数据达到len个字节。

总之这是一个读文件内容的标准操作api。

============================================

5、readDouble() readFloat() readBoolean() readInt()

readLong() readShort() readByte() readChar()

这些方法都是去read每一个字符,个人感觉就是返回他们的ASCII码

当然如果专家们有异议可以指出,我测试的时候至少是这么感觉得。

大家也可以自己试一下。

比如readLong就是要求你的文本内容必须有八个字符,不然会报错。

伴随着也就是

writeDouble() writeFloat() writeBoolean() writeInt()

writeLong() writeShort() writeByte() writeChar()

============================================

6、readFully(byte[] b):

这个方法的作用就是将文本中的内容填满这个缓冲区b。

如果缓冲b不能被填满,那么读取流的过程将被阻塞,

如果发现是流的结尾,那么会抛出异常。

这个过程就比较像“凑齐一车人在发车,不然不走”。

============================================

7、getChannel:它返回的就是nio通信中的file的唯一channel

============================================

8、skipBytes(int n):跳过n字节的位置,相对于当前的point。

 

 

可以看出RandomAccessFile实现了大部分文件输入输出流的方法,但是底层实现中他实现的是DataInput和DataOutput接口,并非是FileInputStream和FileOutputStream。RandomAccessFile使用很多native方法实现了对文件的操作,并且很多native方法跟inputstream都有重叠,比如read0方法。我想这么做可能是为了让这个DataInput接口的职责更明确吧。

RandomAccessFile简介与使用 RandomAccessFile简介与使用

 

从上述对比中可以看出,datainput更注视强化对数据的各种既定操作。并没有出现类似inputstream的方法,也许这就是我们常说的单一职责原则吧。

二、实际操作一下吧

RandomAccessFile简介与使用

定义一个文件

编写一个方便我们使用的工厂类:

public class RAFTestFactory private static final String url = "D:\\EclipseWorkspace\\text\\test.txt"; private static final String [] model = {"r","rw","rws","rwd"}; public static RandomAccessFile getRAFWithModelR() throws FileNotFoundException { RandomAccessFile raf = new RandomAccessFile(new File(url), model[0]); return raf; } public static RandomAccessFile getRAFWithModelRW() throws FileNotFoundException { RandomAccessFile raf = new RandomAccessFile(new File(url), model[1]); return raf; } public static RandomAccessFile getRAFWithModelRWS() throws FileNotFoundException { RandomAccessFile raf = new RandomAccessFile(new File(url), model[2]); return raf; } public static RandomAccessFile getRAFWithModelRWD() throws FileNotFoundException { RandomAccessFile raf = new RandomAccessFile(new File(url), model[3]); return raf; } } 

编写测试类1:

public class RAFTestMain { public static void main(String[] args) throws IOException { RandomAccessFile raf = RAFTestFactory.getRAFWithModelR(); System.out.println("raf.length()->获取文本内容长度:"+raf.length()); System.out.println("raf.getFilePointer()->获取文本头指针:"+raf.getFilePointer()); raf.seek(4); System.out.println("raf.getFilePointer()->第二次获取文本头指针:"+raf.getFilePointer()); } } 

看一下结果,体验一下seek的含义

 

编写测试类2:

public class RAFTestMain { public static void main(String[] args) throws IOException { RandomAccessFile raf = RAFTestFactory.getRAFWithModelR(); raf.write(1); } } 

RandomAccessFile简介与使用

为什么出现这个结果,就是因为我们使用了 R model,也就是只读模式,这是写入会报错。

编写测试类3:

public class RAFTestMain { public static void main(String[] args) throws IOException { RandomAccessFile raf = RAFTestFactory.getRAFWithModelRW(); String word = "ljh"; raf.write(word.getBytes()); } } 

RandomAccessFile简介与使用

可以看到我们写的位置就是当前光标的位置,这个时候让我们结合seek和write试验一下吧。

编写测试类4:

public class RAFTestMain { public static void main(String[] args) throws IOException { RandomAccessFile raf = RAFTestFactory.getRAFWithModelRW(); raf.seek(4); String word = "ljh"; raf.write(word.getBytes()); } } 

RandomAccessFile简介与使用

看,此时我们很方便的实现了插入操作。这是其他类无法实现的功能。也是这个类的强大之处。

 

编写测试类5:

最后我们看看

readDouble() readFloat() readBoolean() readInt() readLong() readShort() readByte() readChar()

writeDouble() writeFloat() writeBoolean() writeInt() writeLong() writeShort() writeByte() writeChar()

他们都怎么用的

public class RAFTestMain { public static void main(String[] args) throws IOException { RandomAccessFile raf = RAFTestFactory.getRAFWithModelRW(); raf.writeByte(3); raf.writeChar('a'); raf.writeShort(5); raf.writeInt(6); raf.writeLong(2343l); raf.writeFloat(8.5f); raf.writeDouble(9.44d); raf.writeBoolean(true); } } 

RandomAccessFile简介与使用

真是仙的不行,反正我是看不出个所以然。

RandomAccessFile简介与使用

 

三、对该工具类的价值分析

1、大型文本日志类文件的快速定位获取数据:

得益于seek的巧妙设计,我认为我们可以从超大的文本中快速定位我们的游标,例如每次存日志的时候,我们可以建立一个索引缓存,索引是日志的起始日期,value是文本的poiniter 也就是光标,这样我们可以快速定位某一个时间段的文本内容

2、并发读写

emmm也是得益于seek的设计,我认为多线程可以轮流操作seek控制光标的位置,从未达到不同线程的并发写操作。

3、更方便的获取二进制文件

通过自带的读写转码(readDouble、writeLong等),我认为可以快速的完成字节码到字符的转换功能,对使用者来说比较友好。

 

后续如果自己有想法,多做实验,多看源码。ok太晚了 睡觉了。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200501.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午10:42
下一篇 2026年3月20日 上午10:42


相关推荐

  • github,gitlab,gitee的区别

    github,gitlab,gitee的区别github 是一个基于 git 实现在线代码托管的仓库 向互联网开放 企业版要收钱 gitee 即码云 是 oschina 免费给企业用的 不用自己搭建环境 gitlab 类似 github 一般用于在企业内搭建 git 私服 要自己搭环境 第一 github 针对企业要收费 那当然是不同意 毕竟都想节约资金 那就还能使用 gitee 或者 gitlab 了 第二 但是码云虽然是免费的 而且不用自己搭环境 但是企业中把项目放在别人的服务器上 始终没有安全感 第三 因此 衍生出了 gitlab 就是用于企业搭私服

    2026年3月26日
    2
  • 对团队中“这是某某某的问题”引起的思考[通俗易懂]

    对团队中“这是某某某的问题”引起的思考

    2022年1月25日
    47
  • DeepSeek提示词库技巧[代码]

    DeepSeek提示词库技巧[代码]

    2026年3月14日
    3
  • IrDA红外通信模块[通俗易懂]

    IrDA红外通信模块[通俗易懂]https://blog.csdn.net/XiaoCaiDaYong/article/details/82596872?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachine

    2025年6月10日
    5
  • STM32—PID控制在直流电机中的应用「建议收藏」

    STM32—PID控制在直流电机中的应用「建议收藏」文章目录一.PID控制算法1.什么是PID2.PID系数的理解Ⅰ.比例(P)部分Ⅱ.积分(I)部分Ⅲ.微分(D)部分3.PID的数字化处理二.位置闭环控制三.速度闭环控制一.PID控制算法1.什么是PIDPID:Proportion-Integral-Differential在过程控制中,我们经常使用的一种算法就是PID算法了,所谓PID控制算法就是对偏差进行比例、积分、微分控制,来使偏差…

    2022年6月5日
    131
  • IntelliJ IDEA 可以使用中文了「建议收藏」

    IntelliJ IDEA 可以使用中文了「建议收藏」1.前言今天IntelliJIdea2020.1正式发布了!最大的一个亮点莫过于开始支持中文了。相信很多英语不好的同学已经期盼已久了。但是感觉登录界面感觉变丑了!建议把文章看完再去升级。2.汉化体验先来看看我的效果,首先要告诉你这是官方汉化包,并不是第三方!我大致看了一圈,个别还没有汉化完毕,可能没有找到合适的描述词汇吧,但是绝大部分已经完成了。这下很多同学可以更方便使…

    2022年6月14日
    133

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号