◉◡◉ 您好,欢迎到访伊成个人站!

认识Java RandomAccessFile类

本文于1626天之前发表,文中内容可能已经过时。

介绍

RandomAccessFile既可以读取文件内容,也可以向文件输出数据。同时,RandomAccessFile支持“随机访问”的方式,程序快可以直接跳转到文件的任意地方来读写数据。

由于RandomAccessFile可以自由访问文件的任意位置,所以如果需要访问文件的部分内容,而不是把文件从头读到尾,使用RandomAccessFile将是更好的选择。

与OutputStream、Writer等输出流不同的是,RandomAccessFile允许自由定义文件记录指针,RandomAccessFile可以不从开始的地方开始输出,因此RandomAccessFile可以向已存在的文件后追加内容。如果程序需要向已存在的文件后追加内容,则应该使用RandomAccessFile。

一个构造函数

RandomAccessFile类有两个构造函数,其实这两个构造函数基本相同,只不过是指定文件的形式不同

  • 一个需要使用String参数来指定文件名

  • 一个使用File参数来指定文件本身

同时还需要指定一个mode参数,该参数指定RandomAccessFile的访问模式,一共有4种模式。

具体如下:

模式 | 说明
|:—:|:—
r | 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException
rw | 打开以便读取和写入
rws | 打开以便读取和写入。相对于 “rw”,”rws” 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备
rwd | 打开以便读取和写入,相对于 “rw”,”rwd” 还要求对“文件的内容”的每个更新都同步写入到基础存储设备

两个重要的方法

由以上介绍得知RandomAccessFile既可以读文件,也可以写文件,所以类似于InputStream的read()方法,以及类似于OutputStream的write()方法,RandomAccessFile都具备。除此之外,RandomAccessFile具备两个特有的方法,来支持其随机访问的特性。

RandomAccessFile对象包含了一个记录指针,用以标识当前读写处的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件指针记录位于文件头,当读/写了n个字节后,文件记录指针将会后移n个字节。除此之外,RandomAccessFile还可以自由移动该记录指针。

下面就是RandomAccessFile具有的两个特殊方法,来操作记录指针,实现随机访问:

  • long getFilePointer( ) // 返回文件记录指针的当前位置
  • void seek(long pos ) // 将文件指针定位到pos位置

写方法

主要有:write(),writeBoolean(),writeByte(),writeBytes(),writeChar(),writeChars()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void write(byte[] b) 
//将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。

void write(byte[] b, int off, int len)
//将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。

void write(int b)
//向此文件写入指定的字节。

void writeBoolean(boolean v)
//按单字节值将 boolean 写入该文件。

void writeByte(int v)
//按单字节值将 byte 写入该文件。

void writeBytes(String s)
//按字节序列将该字符串写入该文件。

void writeChar(int v)
//按双字节值将 char 写入该文件,先写高字节。

void writeChars(String s)
//按字符序列将一个字符串写入该文件。

void writeDouble(double v)
//使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。

void writeFloat(float v)
//使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字

读方法

主要有: read(),readBoolean(),readByte(),readChar(),readDouble(),readFloat(),readFully(),readInt(),readLine()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
int read() 
从此文件中读取一个数据字节。

int read(byte[] b)
将最多 b.length 个数据字节从此文件读入 byte 数组。

int read(byte[] b, int off, int len)
将最多 len 个数据字节从此文件读入 byte 数组。

boolean readBoolean()
从此文件读取一个 boolean

byte readByte()
从此文件读取一个有符号的八位值。

char readChar()
从此文件读取一个字符。

double readDouble()
从此文件读取一个 double

float readFloat()
从此文件读取一个 float

void readFully(byte[] b)
将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。

void readFully(byte[] b, int off, int len)
将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。

int readInt()
从此文件读取一个有符号的 32 位整数。

String readLine()
从此文件读取文本的下一行。

long readLong()
从此文件读取一个有符号的 64 位整数。

short readShort()
从此文件读取一个有符号的 16 位数。

int readUnsignedByte()
从此文件读取一个无符号的八位数。

int readUnsignedShort()
从此文件读取一个无符号的 16 位数。

String readUTF()
从此文件读取一个字符串。

demo1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Test{

static void testWrite() throws IOException {
File file=new File("D:\\test.txt");
if(!file.exists()){
file.createNewFile();
}

RandomAccessFile raf=new RandomAccessFile(file, "rw");
System.out.println("文件指针位置:"+raf.getFilePointer());
raf.writeInt(20);//写入一个int
System.out.println("文件指针位置:"+raf.getFilePointer());
raf.writeBoolean(true);//写入一boolean
raf.close();//关闭文件
}

static void TestRead() throws IOException{
File file=new File("D:\\test.txt");
//随机文件对象
RandomAccessFile raf=new RandomAccessFile(file, "rw");
//写入一个int
int in = raf.readInt();
System.out.println(in);
//写入一boolean
boolean flag= raf.readBoolean();
System.out.println(flag);
raf.close();//关闭文件
}

public static void main(String[] args) throws IOException{
testWrite();
TestRead();
}

}

运行结果:

1
2
3
4
文件指针位置:0
文件指针位置:4
20
true

demo2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.io.FileNotFoundException;  
import java.io.RandomAccessFile;


public class test2 {

public static void main(String[] args) {

try {
//实例化随机存储流,不需要创建文件的路径
RandomAccessFile Raf = new RandomAccessFile("file", "rw");
//创建一个字符串数组并初始化
String[] name = new String[3];
name[0] = "JAVA";
name[1] = "android";
name[2] = "C++";
//遍历数组
for(int i = 0;i<name.length;i++){
//使用随机流将数组写出去
Raf.writeUTF(name[i]);
}

//添加元素
Raf.seek(Raf.length());
Raf.writeUTF("SSH");

//使用seek将Raf.length()执行数组的第一个
Raf.seek(0);

//遍历使用偏移量来遍历,每移动一下就打印出数据
while(Raf.getFilePointer()<Raf.length()){
System.out.println(Raf.readUTF());
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

运行结果:

1
2
3
4
JAVA
android
C++
SSH

运用场景

  1. 断点续传
  2. 快速定位文件某一行
支付宝打赏 微信打赏