特点:
- 既可以读也可以写
- RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件。
- 支持只访问文件的部分内容
- 可以向已存在的文件后追加内容
- RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile 类对象可以自由移动记录指针:
- long getFilePointer(): 获取文件记录指针的当前位置
- void seek(long pos): 将文件记录指针定位到 pos 位置
我们可以用RandomAccessFile这个类,来实现一个多线程断点下载的功能,用过下载工具的朋友们都知道,下载前都会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能,有兴趣的朋友们可以自己实现下。
package com.senior.iostream;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
/**
* @author eden
* @Description
* @create projectTest-com.senior.iostream:2021-05-13-22:49
* @since
*/
public class RandomAccessFileTest {
//写数据+从指定位置开始写数据+末尾写数据
@Test
public void test() {
RandomAccessFile rw = null;
try {
rw = new RandomAccessFile("random.txt", "rw");
//rw.seek(2);//把文件记录指针调整到索引为2的位置开始进行写操作
//先通过File得到文件长度,将文件记录指针移到末尾,然后进行write操作
//其效果类似于在文件末尾插入数据
rw.seek(new File("random.txt").length());//
rw.write("--".getBytes(StandardCharsets.UTF_8));//覆盖数据的作用
} catch (IOException e) {
e.printStackTrace();
} finally {
if(rw!=null)
{
try {
rw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//读数据
@Test
public void test1(){
RandomAccessFile r = null;
try {
r = new RandomAccessFile("random.txt", "r");
//
byte[] bytes = new byte[2];
int len;
while((len = r.read(bytes))!=-1)
{
System.out.print(new String(bytes,0,len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(r!=null)
{
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//从指定位置插入数据
@Test
public void test2() {
RandomAccessFile rw = null;
try {
rw = new RandomAccessFile("random.txt", "rw");
rw.seek(2);//把文件记录指针调整到索引为2的位置
//使用stringBuilder先把从索引位置为2到文件末尾的数据都存起来
//StringBuilder默认容量为16,为避免扩容,直接给其指定文件大小的内存空间
StringBuilder stringBuilder = new StringBuilder((int) new File("random.txt").length());
byte[] bytes = new byte[2];
int len;
while((len = rw.read(bytes))!=-1)
{
stringBuilder.append(new String(bytes,0,len));
}
//再把指针调回来
rw.seek(2);
rw.write("--".getBytes(StandardCharsets.UTF_8));
//再把StringBuilder的数据写入
rw.write(stringBuilder.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(rw!=null)
{
try {
rw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
开发中不一定需要自己去一步步手写IO流,可以利用第三方提供的java包快速实现相关操作。
了解内容: