RandomAccessFile 类
- RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并 且它实现了DataInput、DataOutput这两个接口,也就意味着这个类既可以读也 可以写。
- RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意 地方来读、写文件
1. 支持只访问文件的部分内容
2. 可以向已存在的文件后追加内容 - RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。 RandomAccessFile 类对象可以自由移动记录指针:
1. long getFilePointer():获取文件记录指针的当前位置
2. void seek(long pos):将文件记录指针定位到 pos 位置
RandomAccessFile类的构造器及参数
构造器
- public RandomAccessFile(File file, String mode)
- public RandomAccessFile(String name, String mode)
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:
- r: 以只读方式打开
- rw:打开以便读取和写入
- rwd:打开以便读取和写入;同步文件内容的更新
- rws:打开以便读取和写入;同步文件内容和元数据的更新
如果模式为只读r。则不会创建文件,而是会去读取一个已经存在的文件, 如果读取的文件不存在则会出现异常。 如果模式为rw读写。如果文件不 存在则会去创建文件,如果存在则不会创建。
案例:在指定位置插入数据
- 首先新建一个txt文件,方便测试看到效果,然后采用该方法进行读取文件,并用指针角标进行插入数据
- 然后写一个测试类,采用junit单元测试方法
@Test
public void test2() {
RandomAccessFile raf1 = null;
try {
raf1 = new RandomAccessFile("hello.txt", "rw");
raf1.seek(5);//将指针掉到角标为5的位置
raf1.write("xnch".getBytes());//覆盖数据操作
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:
我们发现,该结果不是我们想要的效果,从设定的指针位置虽然插入进了数据,但是之前的数据被依次覆盖了,显然不是我们想要的效果。接下来我们可以使用一个StringBuilder来存下指针位置后面的数据。
@Test
public void test3() {
RandomAccessFile raf1 = null;
try {
raf1 = new RandomAccessFile("hello.txt", "rw");
raf1.seek(5);//将指针掉到角标位置
//保存指针5后面的所有数据到StringBuilder中
StringBuilder builder = new StringBuilder((int)new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while((len = raf1.read(buffer)) != -1) {
builder.append(new String(buffer,0,len));
}
//调回指针,写入“xnch”
raf1.seek(5);
raf1.write("xnch".getBytes());
//将StringBuilder中的数据写入到文件中
raf1.write(builder.toString().getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}