一、RandomAccessFile类的基本使用
RandomAccessFile类的构造方法,有两种重载形式:
RandomAccessFile(String path,String mode);
RandomAccessFile(File file,String mode);
其中第一个参数是需要访问的文件,第二个参数是访问模式。
void write(int d)
,该方法会在当前指针所在位置处写入一个字节,是将参数int的“低8位”写出。
int read()
,该方法会从文件中读取一个byte(8位)填充到int的低八位,高24位为0,返回值范围正数:0~255,如果返回-1表示读取到了文件末尾。每次读取后自动移动文件指针,准备下次读取。
void close()
,RandomAccessFile在对文件访问的操作全部结束后,要调用close()方法来释放与其关联的所有系统资源。
package day06;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* java.io.RandomAccessFile用来读写文件数据,就是既可以读取文件数据也
* 可以向文件中写入数据。
* RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,并且
* 读写后指针会自动向后移动。
*
* @author xxx
*
*/
public class RandomAccessFileDemo1 {
public static void main(String[] args) throws IOException {
/*
* RandomAccessFile(String path,String mode)
* RandomAccessFile(File file,String mode)
* 第二个参数为模式:常用的有r,只读模式;rw,读写模式。
*/
RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");
/*
* void write(int d)
* 写入给定的int值对应的2进制的低八位
*/
raf.write(2);
System.out.println("写入完毕!");
raf.close();
/*
* int read()
* 读取一个字节,并以10进制的int型返回,若返回值为-1,则表示读取到了文件末尾。
*/
RandomAccessFile raf1 = new RandomAccessFile("raf.dat", "r");
int d = raf1.read();
System.out.println(d);
raf1.close();
}
}
二、字节数据读写操作
void write(byte[] d)
,该方法会在当前指针所在位置处连续写出给定数组中的所有字节。
void write(byte[] d, int offset, int len)
,该方法会在当前指针所在位置处连续写出给定数组中的部分字节,这个部分是从数组的offset处开始,连续len个字节。
int read(byte[] b)
,该方法会从指针位置处尝试最多读取给定数组的总长度的字节量,并从给定的字节数组第一个位置开始,将读取到的字节顺序存放至数组中,返回值为实际读取到的字节量。
package day06;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 复制文件
* @author xxx
*
*/
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("a.txt", "r");
RandomAccessFile des = new RandomAccessFile("b.txt", "rw");
int d = -1;
long start = System.currentTimeMillis();
while ((d = src.read()) != -1) {
des.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:"+(end - start)+"ms");
src.close();
des.close();
}
}
package day06;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 若想提高读写效率,可以通过提高每次读写的数据量来减少读写次数达到。
* @author xxx
*
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("a.txt", "r");
RandomAccessFile des = new RandomAccessFile("b.txt", "rw");
/*
* int read(byte[] date)
* 一次性尝试读取给定的字节数组总长度的字节量并存入到该
* 数组中, 返回值为实际读取到的字节量,若返回值为-1,则表
* 示本次没有读取到任何数据(文件末尾)
*/
byte[] buf = new byte[1024 * 10];//10K
int len = -1;
long start = System.currentTimeMillis();
while ((len = src.read(buf)) != -1) {
/*
* void write(byte[] date)
* 一次性将给定的字节数组中的所有字节写出
*
* void write(byte[] d,int start,int len)
* 将给定数组中从下标start处开始的len个字节一次性的写入
*/
des.write(buf, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:"+(end - start)+"ms");
src.close();
des.close();
}
}
三、基本类型数据的读写和文件指针操作
RandomAccessFile类中专门提供了针对8种基本数据类型的writeXxx()方法和readXxx()方法,具体可以查看Java的API手册。
long getFilePointer()
,该方法用于获取当前RandomAccessFile的指针位置。
void seek(long pos)
,该方法用于移动当前RandomAccessFile的指针位置。
package day06;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* RAF提供了方便读写基本类型数据的方法
* @author xxx
*
*/
public class RandomAccessFileDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf1.dat", "rw");
/*
* long getFilePointer()
* 获取当前RAF的指针位置
*/
System.out.println("pos:"+raf.getFilePointer());
//向文件中写入一个int最大值
int max = Integer.MAX_VALUE;
raf.write(max >>> 24);
System.out.println("pos:"+raf.getFilePointer());
raf.write(max >>> 16);
raf.write(max >>> 8);
raf.write(max);
System.out.println("pos:"+raf.getFilePointer());
raf.writeInt(max);
raf.writeLong(123L);
raf.writeDouble(123.123);
/*
* void seek(long pos)
* 移动指针到指定位置
*/
raf.seek(0);
System.out.println("pos:"+raf.getFilePointer());
//end of file
int i = raf.readInt();
System.out.println(i);
raf.seek(8);
long l = raf.readLong();
System.out.println(l);
System.out.println("pos:"+raf.getFilePointer());
double d = raf.readDouble();
System.out.println(d);
System.out.println("pos:"+raf.getFilePointer());
raf.seek(0);
l = raf.readLong();
System.out.println(l);
raf.close();
}
}
四、文件读写综合小练习
package day06;
/**
* 员工测试类
* @author xxx
*
*/
import java.text.SimpleDateFormat;
import java.util.Date;
public class Emp {
private String name;
private int age;
private String gender;
private int salary;
private Date hiredate;
public Emp() {
}
public Emp(String name, int age, String gender, int salary, Date hiredate) {
super();
this.name = name;
this.age = age;
this.gender = gender;
this.salary = salary;
this.hiredate = hiredate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public String toString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return name+","+age+","+gender+","+salary+","+sdf.format(hiredate);
}
}
package day06;
/**
* 从一个存有员工信息的文件中解析出员工的信息
* @author xxx
*
*/
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Test_13 {
public static void main(String[] args) throws URISyntaxException, IOException, ParseException {
//使用类加载器加载当前包中的emp.dat文件
File file = new File(Test_13.class.getClassLoader().getResource("day06/emp.dat").toURI());
RandomAccessFile raf = new RandomAccessFile(file,"r");
List<Emp> empList = new ArrayList<Emp>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0;i < 10;i++) {
//读取name的字符串
String name = readString(32,raf);
//读取age
int age = raf.readInt();
//读取gender
String gender = readString(10, raf);
//读取salary
int salary = raf.readInt();
//读取日期
String hiredate = readString(30, raf);
Date hire = sdf.parse(hiredate);
Emp emp = new Emp(name, age, gender, salary, hire);
empList.add(emp);
}
raf.close();
System.out.println("解析完毕!");
for (Emp e:empList) {
System.out.println(e);
}
}
public static String readString(int len,RandomAccessFile raf) throws IOException {
byte[] data = new byte[len];
raf.read(data);
return new String(data,"utf-8").trim();
}
}