12.2 RandomAccessFile类
File类只是针对文件本身进行操作,而如果要对文件内容进行操作,则可以使用RandomAccessFile类,此类属于随机读取类,可以随机地读取一个文件中指定位置的数据,例如,现在假设在文件中保存了以下3个数据:
zhangsan,30。
lisi,31。
wangwu,32。
那么如果使用RandomAccessFile类读取"lisi"信息时,就可以将"zhangsan"的信息跳过,相当于在文件中设置了一个指针,根据此指针的位置进行读取。但是如果想实现这样的功能,则每个数据的长度应该保持一致,所以在设置姓名时应统一设置为8位,数字为4位,如图12-4所示。
![]() |
(点击查看大图)图12-4 数据的保存 |
要实现功能,则必须依靠RandomAccess中的几种设置模式,然后在构造方法中传递此模式。此类的常用操作方法如表12-2所示。
表12-2 RandomAccessFile类的常用操作方法
序号 | 方 法 | 类型 | 描 述 |
1 | public RandomAccessFile(File file,String mode) throws FileNotFoundException | 构造 | 接收File类的对象, 指定操作路径,但是在 设置时需要设置模式, r为只读;w为只写; rw为读写 |
2 | public RandomAccessFile(String name,String | 构造 | 不再使用File类对象 表示文件,而是直 接输入了一个固定 的文件路径 |
3 | public void close() throws IOException | 普通 | 关闭操作 |
4 | public int read(byte[] b) throws IOException | 普通 | 将内容读取到一个byte数组中 |
5 | public final byte readByte() throws IOException | 普通 | 读取一个字节 |
6 | public final int readInt() throws IOException | 普通 | 从文件中读取整型数据 |
7 | public void seek(long pos) throws IOException | 普通 | 设置读指针的位置 |
8 | public final void writeBytes(String s) throws | 普通 | 将一个字符串写入到文件中, 按字节的方式处理 |
9 | public final void writeInt(int v) throws | 普通 | 将一个int型数据写入文件, 长度为4位 |
10 | public int skipBytes(int n) throws IOException | 普通 | 指针跳过多少个字节 |
需要注意的是,如果使用rw方式声明RandomAccessFile对象时,要写入的文件不存在,系统将自动进行创建。
12.2.1 使用RandomAccessFile类写入数据
下面写入12.2节的3个数据,为了保证可以进行随机读取,所以写入的名字都是8个字节,写入的数字是固定的4个字节。
范例:写文件
写完后可以直接通过RandomAccess的方式进行随机读取。
- package org.lxh.demo12.randomaccessdemo;
- import java.io.File;
- import java.io.RandomAccessFile;
- public class RandomAccessFileDemo01 {
- // 直接抛出异常,程序中可以不用再分别处理
- public static void main(String[] args)
throws Exception {- File f = new File("d:" + File.separator +
"test.txt"); // 指定要操- 作的文件
- RandomAccessFile rdf = null ; //
声明一个RandomAccessFile类对象- rdf = new RandomAccessFile(f,"rw");//
以读写方式打开文件,会自动创建新- 文件
- String name = null ;
- int age = 0 ;
- name = "zhangsan" ;
// 字符串长度为8- age = 30 ;
// 数字长度为4- rdf.writeBytes(name);
// 将姓名写入文件之中- rdf.writeInt(age) ;
// 将年龄写入文件之中- name = "lisi " ;
// 字符串长度为8- age = 31 ;
// 数字长度为4- rdf.writeBytes(name);
// 将姓名写入文件中- rdf.writeInt(age) ;
// 将年龄写入文件中- name = "wangwu " ;
// 字符串长度为8- age = 32 ;
// 数字长度为4- rdf.writeBytes(name);
// 将姓名写入文件中- rdf.writeInt(age) ;
// 将年龄写入文件中- rdf.close() ;
// 关闭文件- }
- }
12.2.2 使用RandomAccessFile类读取数据
读取时直接使用r的模式即可,以只读的方式打开文件。
读取时所有的字符串只能按照byte数组的方式读取出来,而且所有的长度是8位。
范例:随机读取
- package org.lxh.demo12.randomaccessdemo;
- import java.io.File;
- import java.io.RandomAccessFile;
- public class RandomAccessFileDemo02 {
- // 直接抛出异常,程序中可以不用再分别处理
- public static void main(String[] args)
throws Exception {- File f = new File("d:" + File.separator
+ "test.txt");// 指定要操作- 的文件
- RandomAccessFile rdf = null ;
// 声明一个RandomAccessFile- 类对象
- rdf = new RandomAccessFile(f,"r") ;
// 以读方式打开文件,会自动创建- 新文件
- String name = null ;
- int age = 0 ;
- byte b[] = new byte[8] ;
// 准备空间读取姓名- rdf.skipBytes(12) ;
- for (int i = 0; i < b.length; i++) {
- b[i] = rdf.readByte();
// 循环读取出前8个内容- }
- name = new String(b) ;
// 将读取出来的byte数组变为String- age = rdf.readInt() ;
// 读取数字- System.out.println("第二个人的信息
--> 姓名:" + name + ";年龄:" + age) ;- rdf.seek(0) ;
// 指针回到文件的开头- b = new byte[8] ;
// 准备空间读取姓名- for (int i = 0; i < b.length; i++) {
- b[i] = rdf.readByte();
// 循环读取出前8个内容- }
- name = new String(b) ;
// 将读取出来的byte数组变为String- age = rdf.readInt() ;
// 读取数字- System.out.println("第一个人的信息
--> 姓名:" + name + ";年龄:" + age) ;- rdf.skipBytes(12) ;
// 跳过第1个人的信息- b = new byte[8] ;
// 准备空间读取姓名- for (int i = 0; i < b.length; i++)
{- b[i] = rdf.readByte();
// 循环读取出前8个内容- }
- name = new String(b) ;
// 将读取出来的byte数组变为String- age = rdf.readInt() ;
// 读取数字- System.out.println("第三个人的信息
--> 姓名:" + name + ";年龄:" + age) ;- rdf.close() ;
// 关闭文件- }
- }
程序运行结果:
- 第二个人的信息 --> 姓名:lisi ;年龄:31
- 第一个人的信息 --> 姓名:zhangsan;年龄:30
- 第三个人的信息 --> 姓名:wangwu ;年龄:32
可以发现,程序中可以随机跳过12位读取信息,也可以回到开始点重新读取。
随机读写流可以实现对文件内容的操作,但是一般情况下操作文件内容往往会使用字节或字符流。