功能简介
我们之前一直说流是顺序的,不能随机访问,的确之前说的IO体系的确如此,但是 RandomAccessFile自成一派,此类的实例支持对随机访问文件的读取和写入。
我们之前介绍过DataOutput 和DataInput,这是两个接口,约定了从基本数据类型与字节的操作交互方式。所以,我们从类层级结构也可以想得到,他必然是提供了便捷的读写基本数据类型的方法。
— 2 —
构造方法
既然是文件随机读写,自然需要文件,内部维护了一个文件描述符 fd,还有文件的读写方式 rw。
明明只有两个构造方法,path的注释还说,如果通过文件描述符创建,path为null;
此处提醒,有些注释或者API文档,他可能没及时删除,也可能没及时修改,如果有的地方明显不太对劲,不要非去找证据证明他是对的,他可能就是错的,就看代码就好了,JDK的源码也是人写的,不是神丢向人间的。
构造方法需要文件,以及读写模式这两个信息来打开文件
mode的字符串形式有如下几种,如果入参不对,可以看得到,如果这几种不是 imode为-1 小于0 直接抛异常了;
"r" 以只读方式打开,调用结果对象的任何 write 方法都将导致抛出 IOException。 "rw" 打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件。 "rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 "rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。
构造方法中会打开文件,文件的打开使用的是本地方法。
— 3 —
RandomAccessFile逻辑原理
RandomAccessFile仅仅只能用于文件
RandomAccessFile 对于文件的操纵,就好像是对于一个巨大的数组进行访问一样存在着一种类似下标索引的东西,可以叫做文件指针至于到底怎么抽象成这个模型的,底层的实现我们不去关注,我们只关注我们看起来RandomAccessFile的样子就好;
如上图所示,这就是RandomAccessFile访问文件的模型
可以返回这个文件的文件描述符 FileDescriptor getFD();
可以返回当前的文件指针 native long getFilePointer();
可以返回文件的长度 native long length();
还可以设置文件的长度 native void setLength(long newLength);
设置读写偏移量位置 void seek(long pos);
setLength 为什么还能设置文件长度? 你可以理解为这是一个"动态数组"!!
假设你想要设置为newLength 长度1. 如果这个长度小于 实际长度(length方法返回的值), 文件被截断,并且如果getFilePointer 大于newLength,那么它将变成newLength ;2. 如果 newLength大于 实际长度(length方法返回的值),则该文件将被扩展,在此情况下,未定义文件扩展部分的内容;seek方法设置的偏移量,下一次的读写将从这个位置开始。偏移量的设置可能会超出文件末尾,这并不会改变什么但是一旦你在这个超出文件末尾的偏移量位置写入数据,长度将会改变
也正是此处的这几个方法提供了随机访问的能力
— 4 —
方法简介
RandomAccessFile的神秘之处就在于它的逻辑原理,那就是呈现给我们的操作方式就像操作数组一样,他根本的读写方法,全都是本地方法
对于其他的readXXX 以及writeXXX方法
则是借助于基本的读写方法的情况下, 提供了对基本数据类型的支持
这一部分就相当于把DataInputStream和DataOutputStream结合起来了
而且还能够随机存取
不再对readXXX和 writeXXX方法进行介绍
如有兴趣可以对DataInput DataOutput 以及 DataInputStream和DataOutputStream 进行深入研究。
https://mp.weixin.qq.com/s/yds5IYq75NPwq6t_CH7bBQ