RandomAcessFile类基本使用详解
目录
1、构造函数
2、常用的方法
--2.1、最基本的方法----read()和write()
--2.2、其他的读写方法
3、RandomAcessFile文件复制
java.io.RandomAcessFile
可以对文件进行随机的读取和写入。
1、构造函数
//创建从中读取和向其中写入的随机访问文件流,该文件由File参数指定
public RandomAcessFile(File file,String mode);
//创建从中读取和向其中写入的随机访问文件流,该文件具有指定的名称
public RandomAccessFile(String name,String mode);
参数说明:
r
:readw
:writes
:synchronouslyd
:device
mode:
r
:以只读方式打开
rw
:以读写方式打开(如果使用的是上面的第一个构造函数,如果该文件不存在,则尝试创建该文件)
rws
:以读写方式打开,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。rws
模式是同步模式,你每写入一个字节的数据,数据就立马写入到设备上面,可以保证由该调用对此文件所做的所有更改均被写入该设备。这对确保在系统崩溃时不会丢失重要信息特别有用。
rwd
:以读写方式打开,还要求对文件的内容的每个更新都同步写入到底层存储设备。rwd
模式可用于减少执行的 I/O 操作数量。
使用 rwd
仅要求更新要写入存储的文件的内容;使用 rws
要求更新要写入的文件内容及其元数据,这通常要求至少一个以上的低级别 I/O 操作。
2、常用的方法
2.1、最基本的方法----read()和write()
//从此文件中读取一个数据字节(8bit)
public int read();
//向此文件中写入一个数据字节(8bit)
public int write(int b);
我们都知道在Java中int占4个字节(32bit),如果我们要将一个int数据写入到文件中那么每次只能写入1个字节,就意味着我们必须要将int型数据拆分为4次来写入到文件中,同样的,在读取数据的时候也是一样的。
import java.io.File;
import java.io.RandomAccessFile;
/**
* RandomAccessFile随机访问文件的读取和写入
* 在这里我们new两个RandomAccessFile的实例出来,一个用来向文件中存入数据,另一个用来读取文件中的数据,假设demo.dat文件已经存在
* @author Administrator
*
*/
public class RandomAccessFileDemo01 {
public static void main(String[] args){
try {
//构造方法一,该实例用来向文件中写入数据
RandomAccessFile raf=new RandomAccessFile("demo.dat", "rw");
//构造方法二,该实例用来读取文件中的数据
File file=new File("demo.dat");
RandomAccessFile raf1=new RandomAccessFile(file, "rw");
/**
* public void write(int b)throws IOException
* 每次只写入一个字节,写入整数的"低8位"
*/
int x=999999999;//二进制表示为:00111011 10011010 11001001 11111111
raf.write((x>>>24)&0xff);//写入高8位:00111011
System.out.println(Integer.toBinaryString((x>>>24)&0xff));
raf.write(x>>>16&0xff);//写入中上8位:10011010
System.out.println(Integer.toBinaryString((x>>>16)&0xff));
raf.write(x>>>8&0xff);//写入中下8位:11001001
System.out.println(Integer.toBinaryString((x>>>8)&0xff));
raf.write(x);//写入低8位置:11111111
System.out.println(Integer.toBinaryString((x>>>0)&0xff));
raf.close();
/**
* 从当前文件中读取一个字节,将该字节存入返回的int中
* 若返回值为-1,则说明读取到了文件的末尾(EOF:END OF FILE)
*/
int a=raf1.read();
int b=raf1.read();
int c=raf1.read();
int d=raf1.read();
//将每次读取出来的数据依次算术移位
int readX=(a<<24)+(b<<16)+(c<<8)+(d);
System.out.println("读取出来的数据为:"+readX);
raf1.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
有人会说这样做好麻烦啊!是的,这样做确实是很麻烦,强大的Java已经给我们封装好了其他的方法了,但是,我们通过查看源码可以知道其他已经封装好的方法都是以上面所述的方法为基础的。
2.2、其他的读写方法:
//将最多 b.length 个数据字节从此文件读入 byte 数组
public int read(byte[] b);
//将 b.length 个字节从指定 byte 数组写入到此文件
public void write(byte[] b);
//最多 len 个数据字节从此文件读入 byte 数组,off是写入数据时字节数组b中的初始偏移量
public int read(byte[] b,int off,int len);
//将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始
public void write(byte[] b,int off,int len);
//从此文件读取一个 boolean。此方法从该文件的当前文件指针开始读取单个字节。值 0 表示 false。其他任何值表示 true
public final boolean readBoolean();
//按单字节值将 boolean 写入该文件
public final void writeBoolean(boolean v);
//从此文件读取一个有符号的八位值。此方法从该文件的当前文件指针开始读取一个字节
public final byte readByte();
//按单字节值将 byte 写入该文件
public final void writeByte(int v);
//按字节序列将该字符串写入该文件。该字符串中的每个字符均按顺序写出,并丢弃其高八位
public final void writeBytes(String s);
//从此文件读取一个字符。此方法从该文件的当前文件指针开始读取两个字节
public final char readChar();
//按双字节值将 char 写入该文件,先写高字节
public final void writeChar(int v);
//按字符序列将一个字符串写入该文件。每个字符均写入数据输出流
public final void writeChars(String s);
//从此文件读取一个 double
public final double readDouble();
//使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节
public final void writeDouble(double v);
//从此文件读取一个 float
public final float readFloat();
//使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节
public final void writeFloat(float v);
//从此文件读取一个有符号的 32 位整数。此方法从该文件的当前文件指针开始读取 4 个字节
public final int readInt();
//按四个字节将 int 写入该文件,先写高字节
public final void writeInt(int v);
//从此文件读取一个有符号的 64 位整数。此方法从该文件的当前文件指针开始读取八个字节
public final long readLong();
//按八个字节将 long 写入该文件,先写高字节
public final void writeLong(long v);
以上基本上就是RandomAcessFile类所有的读写方法
3、RandomAcessFile文件复制:
import java.io.RandomAccessFile;
public class RandomAccessFileDemo02 {
public static void main(String[] args) {
/**
* 案例:两个文件之间的复制
* 1.先new一个RandomAcessFile用来读取文件里面的数据
* 2.继续new一个RandomAcessFile用户写入读取到的数据
* 3.直到读取数据的返回值为-1时则说明读取完毕
*/
try {
//可以使用大概5MB大小的文件来测试
long begin=System.currentTimeMillis();
RandomAccessFile src=new RandomAccessFile("src.txt", "rw");
RandomAccessFile dest=new RandomAccessFile("dest.txt", "rw");
/**
* 按一个字节一个字节的读取
* 按一个字节一个字节的写入
*
*/
int flag=0;
while((flag=src.read())!=-1){
dest.write(flag);
}
if(flag==-1){
System.out.println("文件复制成功!");
}else{
System.out.println("文件复制失败!");
}
src.close();
dest.close();
long end=System.currentTimeMillis();
System.out.println("按字节读写的时间为:"+(end-begin));
/**
* 使用字节数组来读取和写入
*/
long begin1=System.currentTimeMillis();
RandomAccessFile src1=new RandomAccessFile("src1.txt", "rw");
RandomAccessFile dest1=new RandomAccessFile("dest1.txt", "rw");
//建立一个文件缓冲区,每次读取buffer.length大小的数据
byte[] buffer=new byte[1024*8];
int flag1=0;
//每一次循环读写的数据量为1024*8个字节的数组,返回值为实际读到的字节数
while((flag1=src1.read(buffer))!=-1){
dest1.write(buffer);
}
if(flag1==-1){
System.out.println("文件复制成功!");
}else{
System.out.println("文件复制失败!");
}
src1.close();
dest1.close();
long end1=System.currentTimeMillis();
System.out.println("按字节数组读写的时间为:"+(end1-begin1));
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
文件复制成功!
按字节读写的时间为:22148
文件复制成功!
按字节数组读写的时间为:12
以上的数据说明,我们如果要提高文件的读写效率,那么就要减少I/O的次数。