首页 > 编程笔记 > Java笔记 阅读:11

Java中的RandomAccessFile类(附带实例)

Java 提供的 RandomAccessFile 类,允许从文件的任何位置进行数据的读写。

RandomAccessFile 不属于流,是 Object 类的子类,但它融合了 InputStream 类和 OutStream 类的功能,既能提供 read() 方法和 write() 方法,还能提供更高级的直接读写各种基本数据类型数据的读写方法,如 readInt() 方法和 writeInt() 方法等。

RandomAccessFile 类的中文含义为随机访问文件类,随机意味着不确定性,指的是不需要从头读到尾,可以从文件的任意位置开始访问文件。使用 RandomAccessFile 类,程序可以直接跳到文件的任意地方读、写文件,既支持只访问文件的部分数据,又支持向已存在的文件追加数据。

为支持任意读写,RandomAccessFile 类将文件内容存储在一个大型的 byte 数组中。RandomAccessFile 类设置指向该隐含的 byte 数组的索引,称为文件指针,通过从文件开头就开始计算的偏移量来标明当前读写的位置。

RandomAccessFile 类有两个构造方法,其实这两个构造方法基本相同,只是指定文件的形式不同而已。一个使用 String 参数来指定文件名,一个使用 File 参数来指定文件本身。具体示例如下:
// 访问file参数指定的文件,访问的形式由mode参数指定
public RandomAccessFile(File file, String mode)
// 访问name参数指定的文件,访问的形式由mode参数指定
public RandomAccessFile(String name, String mode)

在创建 RandomAccessFile 对象时还要设置该对象的访问形式,具体使用一个参数 mode 进行指定,mode 的值及其对应的访问形式如下表所示。

表:mode 的值及其含义
mode值 含义
"r" 以只读的方式打开,如果试图对该 RandomAccessFile 执行写入方法,都将抛出 IOException 异常
"rw" 以读、写方式打开指定文件,如果该文件不存在,则尝试创建该文件
"rws" 以读、写方式打开指定文件,相较于"rw"模式,还需要将文件的内容或元数据的每个更新都同步写入底层存储设备
"rwd" 以读、写方式打开指定文件,相较于"rw"模式,还要求将文件内容的每个更新都同步写入底层存储设备

随机访问文件是由字节序列组成,一个称为文件指针的特殊标记定位这些字节中的某个字节的位置,文件的读写操作就是在文件指针所在的位置进行的。打开文件时,文件指针置于文件的起始位置,在文件中进行读写数据后,文件指针就会移动到下一个数据项。

如下表所示,列出了 RandomAccessFile 类所拥有的用来操作文件指针的方法。

表:RandomAccessFile 类操作指针的方法
方法 方法描述
long getFilePointer() 获取当前读写指针所处的位置
void seek(long pos) 指定从文件起始位置开始的指针偏移量,即设置读指针的位置
int skipBytes(int n) 使读写指针从当前位置开始,跳过 n 个字节
void setLength(long num) 设置文件长度

接下来,通过案例来演示 RandomAccessFile 类操作文件指针的方法的使用。
import java.io.*;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Demo {
    public static void main(String[] args) {
        File file = new File("d:/javaCode/test.txt");
        RandomAccessFile raf = null;
        try{
            raf = new RandomAccessFile(file,"rw");
            for(int n = 0;n < 10;n++){
                raf.writeInt(n);
            }
            System.out.println("当前指针位置:" + raf.getFilePointer());
            System.out.println("文件长度:" + raf.length() + "字节");
            raf.seek(0); // 返回数据的起始位置
            System.out.println("当前指针位置:" + raf.getFilePointer());
            System.out.println("读取数据");
            for(int n = 0;n < 6;n++){
                System.out.println("数值:" + raf.readInt() + "---->" + (raf.getFilePointer() - 4));
                if(n == 3)raf.seek(32); // 指针跳过4,5,6,7
            }
        } catch (IOException e){
            e.printStackTrace();
        }
        raf.close(); // 关闭随机访问文件流
    }
}
程序的运行结果如下:

当前指针位置:40
文件长度:40字节
当前指针位置:0
读取数据
数值:0-->0
数值:1-->4
数值:2-->8
数值:3-->12
数值:8-->32
数值:9-->36

程序中,先向 test.txt 文件写入 0~9 这 10 个数字,此时文件的长度为 10 个字节,数据指针位置为 40。

如果要读取文件的数据信息,则需要把文件指针移动到文件的起始位置,而执行 seek(0) 可以达到目的。虽然开始时会循环读取数据,但在 i 为 3 时,将指针移动到 32,即跳过 4、5、6、7,直接开始读取 8 和 9,对应指针位置是 32 和 36。

相关文章