[Java开发之路](7)RandomAccessFile类详解
最后更新于:2022-04-01 09:59:39
RandomAccessFile适用于大小已知的记录组成的文件,提供的对文件访问,既可以读文件,也可以写文件,并且支持随机访问文件,可以访问文件的任意位置。文件中记录的大小不一定都相同,只要我们知道记录的大小和位置。但是该类仅限于操作文件。
RandomAccessFile不属于InputStream和OutputStream继承层次结构中的一部分。除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个继承层次结构没有任何关系,它甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,从头开始编写其所有的方法(大多数都是本地的)。这么做是因为RandomAccessFile拥有和别的IO类型本质上不同的行为,因为我们可以在一个文件内向前和向后移动。它是一个直接继承Object的,独立的类。
本质上说,RandomAccessFile的工作方式类似于把DataInputStream和DataOutputStream结合起来,还添加了一些方法,其中方法getFilePointer( )用来查找当前所处的文件位置,seek( )用来在文件内移至新的位置,length( )用来判断文件大小。此外,它的构造方法还需要一个参数来表示打开模式(只读方式 r 读写方式 rw),它不支持只写文件。
只有RandomAccessFile支持搜寻方法(seek()),并且这个方法也只适用于文件。BufferedInputStream却只能允许标注(mark())位置(其值存储在内部某个变量内)和重新设定位置(reset()),但是这些功能有限,不是非常实用。
在JDK 1.4中,RandomAccessFile的绝大多数功能(但不是全部)已经被nio内存映射文件给取代了。
**方法:**
| 方法 | 描述 |
|-----|-----|
| void close() | 关闭此随机访问文件流并释放与该流关联的所有系统资源。 |
| FileChannel getChannel () | 返回与此文件关联的唯一 FileChannel 对象。 |
| FileDescriptor getFD () | 返回与此流关联的不透明文件描述符对象。 |
| long getFilePointer () | 返回此文件中的当前偏移量,用来查找当前所处的位置。 |
| long length() | 返回此文件的长度。 |
| 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() | 从此文件读取一个字符串。 |
| void seek(long pos) | 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 |
| void setLength(long newLength) | 设置此文件的长度。 |
| int skipBytes(int n) | 尝试跳过输入的 n 个字节以丢弃跳过的字节。 |
| 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,然后按四字节数量将该 int 值写入该文件,先写高字节。 |
| void writeInt(int v) | 按四个字节将 int 写入该文件,先写高字节。 |
| void writeLong(long v) | 按八个字节将 long 写入该文件,先写高字节 |
| void writeShort(int v) | 按两个字节将 short 写入该文件,先写高字节。 |
| void writeUTF(String str) | 使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。 |
**案例:**
~~~
package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Arrays;
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}//if
// 读写方式打开文件
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// write 从当前指针开始写入,写入一个字节
randomAccessFile.write('A');
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
randomAccessFile.write('B');
int num = 0x7fffffff;
// 如果用write方法,每次只能写一个字节,需要写4次
randomAccessFile.write(num >>> 24);
randomAccessFile.write(num >>> 16);
randomAccessFile.write(num >>> 8);
randomAccessFile.write(num);
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// 或者是用writeInt方法 一次写入
randomAccessFile.writeInt(num);
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// 文件指针指向文件开头
randomAccessFile.seek(0);
// 一次性读取 把文件中内容都读到字节数组中
byte[] buffer = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(buffer);
for (byte b : buffer) {
// 16进制输出
System.out.print(Integer.toHexString(b)+" ");
}//for
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~
~~~
package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}//if
// 读写方式打开文件
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// 写值
for(int i = 0;i < 5;++i){
randomAccessFile.writeInt(i);
}//for
// 将文件指针移到第二个Int值后
randomAccessFile.seek(2*4);
// 覆盖第三个Int值
randomAccessFile.writeInt(6);
// 文件指针指向文件开头
randomAccessFile.seek(0);
// 输出
for (int i = 0;i < 5;++i) {
System.out.print(randomAccessFile.readInt()+" ");
}//for
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~
~~~
package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// 以下向file文件中写数据
// 占4个字节
randomAccessFile.writeInt(2015);
// 占8个字节
randomAccessFile.writeDouble(12.23);
// 占2个字节
randomAccessFile.writeShort(19);
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
randomAccessFile.writeUTF("欢迎来到小斯的博客");
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
// 占2个字节
randomAccessFile.writeChar('Y');
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
randomAccessFile.writeUTF("小斯的博客欢迎你");
// 把文件指针位置设置到文件起始处
randomAccessFile.seek(0);
System.out.println("读取一个Int值:"+randomAccessFile.readInt());
System.out.println("读取一个Double值:"+randomAccessFile.readDouble());
System.out.println("读取一个Short值:"+randomAccessFile.readShort());
System.out.println("读取一个字符串:"+randomAccessFile.readUTF());
// 将文件指针跳过2个字节
randomAccessFile.skipBytes(2);
System.out.println("读取一个字符串:"+randomAccessFile.readUTF());
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~