RandomAccessFile 不属于 IO 流,支持对文件的读取和写入随机访问public class RandomAccessFile implements DataOutput, DataInput, Closeable
- DataInput接口中定义了基本数据类型的读操作,例如readInt/readDouble等
- DataOutput接口定义了基本数据类型的写操作,例如writeInt/writeDouble等
RandomAccessFile 是 Java 输入 / 输出流体系中功能最丰富的文件内容访问类,既可以读取文件内容,也可以向文件输出数据。
RandomAccessFile 类在创建对象时,除了指定文件本身,还需要指定一个 mode 参数指定RandomAccessFile的访问模式,该参数有如下四个值:
- r以只读方式打开指定文件。如果试图对该RandomAccessFile指定的文件执行写入方法则会抛出IOException
- rw以读取、写入方式打开指定文件。如果该文件不存在,则尝试创建文件
- rws以读取、写入方式打开指定文件。相对于rw模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备,默认情形下(rw模式下),是使用buffer的,只有cache满的或者使用RandomAccessFile.close()关闭流的时候儿才真正的写到文件
- rwd与rws类似,只是仅对文件的内容同步更新到磁盘,而不修改文件的元数据


读取文件时如果到文件结尾是抛出异常EOFException,所以采用的是异常用于判断文件结束
典型应用:多线程下载和断点续传
- package com.yan2;
-
- import java.io.RandomAccessFile;
-
- public class Test2 {
- public static void main(String[] args) throws Exception {
- RandomAccessFile raf = new RandomAccessFile("data/out1.data", "rw");// rw读写方式
- // 8种简单类型及其包装类和字符串类型
- // raf.writeLong(1L);
- // raf.writeUTF("何xx");
- // raf.writeDouble(1234.56);
- // raf.close();
-
- long id = raf.readLong();
- String name = raf.readUTF();
- double price = raf.readDouble();
- System.out.println("id=" + id + ",name=" + name + ",price=" + price);
- raf.close();
- // 读取文件时如果到文件结尾是抛出异常EOFException,所以这里采用
- // 的是异常用于判断文件结束
- // 典型应用:多线程下载和断点续传
- }
- }
与普通的输入 / 输出流不同的是 : RandomAccessFile 支持跳到文件任意位置读写数据,RandomAccessFile 对象包含一个记录指针,用以标识当前读写处的位置,当程序创建一个新的RandomAccessFile对象时,该对象的文件记录指针对于文件头(也就是 0 处),当读写 n 个字节后,文件记录指针将会向后移动n 个字节。除此之外, RandomAccessFile 可以自由移动该记录指针RandomAccessFile 包含两个方法来操作文件记录指针:文件指针是按照字节数进行统计,取值范围为[0,file.length()]
- long getFilePointer():返回文件记录指针的当前位置
- void seek(long pos):将文件记录指针定位到pos位置
- skipByte(int step); 相对当前位置跳过step个字节
如果文件中间的内容需要进行修改,注意新内容中的字串和原始文件内容的长度应该一致,否则可能会导致修改数据后面的内容无法正常读取
void close() 关闭操作int read(byte[] b) 将内容读取到一个 byte 数组之中byte readByte() 读取一个字节int readInt() 从文件中读取整型数据 … readDouble() 等 8 种简单类型String readLine() 读取一行数据void writeBytes(String s) 将一个字符串写入到文件之中,按字节的方式处理。 writeCharsvoid writeInt(int v) 将一个 int 型数据写入文件,长度为 4 位。 …writeDouble 等 8 种类型
创建文件读写学生就业信息1 、数据格式:学号 (long 没有任何含义,仅仅是一个编号 ) 、姓名 (String) 、就业单位( String )、就业薪资(double)
- package com.yan2;
-
- import java.io.EOFException;
- import java.io.RandomAccessFile;
-
- //数据格式:学号(long没有任何含义,仅仅是一个编号)、姓名(String)、
- //就业单位(String)、就业薪资(double)
- public class Test7 {
- public static void main(String[] args) {
- try (RandomAccessFile raf = new RandomAccessFile("data/out6.data", "rw");) {
- // for (int i = 0; i < 5; i++) {
- // raf.writeLong(1);
- // raf.writeUTF("青海" + i);
- // raf.writeUTF("打字复印");
- // raf.writeDouble(i * 2000 + 1);
- // }
-
- for (int i = 0; i < 100; i++) {
- try {
- long id = raf.readLong();
- String name = raf.readUTF();
- String work = raf.readUTF();
- double price = raf.readDouble();
- System.out.println(id + ":" + name + ":" + work + ":" + price);
- } catch (EOFException e) {
- break;
- }
- }
- // raf.seek(56);
- // raf.writeUTF("放羊放牛");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
练习题:使用随机文件流类 RandomAccessFile 将一个文本文件倒置读出
- package com.yan2;
-
- import java.io.RandomAccessFile;
-
- //使用随机文件流类RandomAccessFile将一个文本文件倒置读出
- public class Test8 {
- public static void main(String[] args) throws Exception {
- // 如果文件已经存在,则重新开始写入内容,原始内容会被替换,未被替换的内容报错不变
- RandomAccessFile raf = new RandomAccessFile("data/out7.txt", "rw");
-
- // raf.writeUTF("停车坐爱枫林晚1");// UTF-8
- // System.out.println(raf.getFilePointer());
-
- // String ss = "xx何是狗傻";
- // raf.writeChars(ss);
- // System.out.println(raf.getFilePointer());
-
- long kk = raf.length();
- // System.out.println(kk);
- for (kk -= 2; kk >= 0; kk -= 2) {
- raf.seek(kk);
- char ch = raf.readChar();
- System.out.print(ch);
- }
-
- raf.close();
- }
- }