RandomAccessFile声明在java.io包下,但直接继承Object类,并且实现了DataInput和DataOutPut这两个接口,即这个类也可以读也可以写,RandomAccessFile类支持随机访问的方式,程序可以跳转到文件的任意位置读取文件。
支持只访问文件的部分内容,可以向已存在的文件后追加内容。
RandomAccessFile对象包含一个记录指针,用以指示当前读写处的位置,RandomAccessFile类对象可以自由移动记录指针。
创建RandomAccessFile对象时,需要指定一个mode参数,该参数代表访问文件的权限,
r: 以只读方式打开
rw: 打开以便读取与写入
rwd: 打开以便读取与写入,同步文件内容的更新。
rws: 打开以便读取与写入,同步文件内容和元数据的更新。
对于文本文件,用RandomAccessFile作为输出流,写出文件如果不存在,则新建此文件,如果写出文件存在,则会对原有的文件内容进行覆盖(默认情况下是从头覆盖)
使用RandomAccessFile类复制图片文件
/**
* 使用RandomAccessFile类复制图片文件
*/
@Test
public void test1() {
//1:创建对象
RandomAccessFile in = null;
RandomAccessFile out = null;
try {
//r参数代表只读文件
in = new RandomAccessFile("图片1.png", "r");
//rw参数代表可读可写文件
out = new RandomAccessFile("图片4.png", "rw");
//创建一个字节数组
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
if (in != null) {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
使用RandomAccessFile类对文件内容的覆盖
/**
* 使用RandomAccessFile类对文件内容的覆盖
* 默认从头进行覆盖
*/
@Test
public void test2() {
RandomAccessFile out = null;
try {
out = new RandomAccessFile("test1.txt", "rw");
String content = "XYZ";
byte[] bytes = content.getBytes();
out.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
if (out != null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试结果
abcdefghigklmn //运行之前
XYZdefghigklmn //运行之后
使用RandomAccessFile类在文本文件的指定位置插入数据
/**
* 使用RandomAccessFile类在文本文件的指定位置插入数据
*/
@Test
public void test3() {
RandomAccessFile out = null;
try {
//需要操作的文件
File file = new File("test1.txt");
out = new RandomAccessFile("test1.txt", "rw");
//获取文件的长度
long length = file.length();
//需要插入数据的位置
int index = 3;
//记录文件中位置3后的数据
StringBuilder sb = new StringBuilder();
//设置指针的位置为3,从0开始
out.seek(index);
byte[] b = new byte[20];
int len = 0;
while ((len = out.read(b)) != -1) {
sb.append(new String(b, 0, len));
}
//重新将指针设置到3位置
out.seek(index);
//需要插入的数据内容
String content = "XYZ";
//写入需要追加的数据
out.write(content.getBytes());
//写入原来末尾的数据
out.write(sb.toString().getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
if (out != null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试结果
abcdefghigklmn //运行之前
abcXYZdefghigklmn //运行之后