Java文件操作(二)
RandomAccessFile 类
1、向文件中写入数据
java.io.RandomAccessFile类: 随机访问文件(RAF)
RAF 是专门用力读写文件的 API, 其基于指针对文件任意位置进行读写操作, 因此读写方式灵活.
- RandomAccessFile构造器
- RandomAccessFile(File file, String mode)
- RandomAccessFile(String fileName, String mode)
- 第一个参数为要操作的文件, 第二个参数为操作模式
- 操作模式是一个字符串, 支持两个值:
- “r”: 只读模式, 仅对文件做读取操作。 r : read 读
- “rw” : 读写操作, 对文件即可读又可写。 w : write 写
/**
* @author taoyi
* @version 1.0
* @date 2021/3/24 16:02
*
* 本类用于测试 java.io.RandomAccessFile类 随机访问文件
* RAF 是专门用力读写文件的 API, 其基于指针对文件任意位置进行读写操作, 因此读写方式灵活
*/
public class RAFDemo {
public static void main(String[] args) {
// 想对当前目录下的 raf.dat 文件进行操作
RandomAccessFile raf = null;
File file = new File(".\\raf.dat");
/**
* RAF在创建时,若指定的文件不存在,则根据操作模式不同,结果不同.
* 如果指定的是rw模式,则会将该文件创建出来.
* 如果指定的是r模式,则会抛出异常FileNotFoundException,告知该文件不存在!
*/
try {
raf = new RandomAccessFile(file,"rw");
try {
/**
* void write(int d)
* 向文件中写入一个字节,写入的是给定的int值所对应的2进制的"低八位"
* int:1
* vvvvvvvv
* 2进制:00000000 00000000 00000000 00000001
*/
// 向文件中写入一个字节, 写入的是给定的 int 值所对应的二进制的“低八位”
raf.write(1); //00000000 00000000 00000000 00000001
raf.write(2); //00000000 00000000 00000000 00000010
/**
** 写入操作执行完毕后,raf.dat文件内容
* 00000001 00000010
*/
System.out.println("写入成功!");
} catch (IOException e) {
System.out.println("写入失败!");
e.printStackTrace();
}
System.out.println("执行完毕!");
} catch (FileNotFoundException e) {
System.out.println("执行失败!");
e.printStackTrace();
}finally {
try {
raf.close();//当使用RAF读写完毕后,最终要调用close方法释放资源.
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、从文件中读取数据
int read()方法
从文件中读取1个字节,返回值值为 int 型,该 int 值对应的2进制的"低八位"就是本次读取出来的字节内容.如果返回的 int 值是 -1 则表示读取到了文件的末尾(EOF)。
EOF:end of file 文件末尾
/**
* @author taoyi
* @version 1.0
* @date 2021/3/24 16:53
*
* 本类用于测试从文件中读取数据
*/
public class RAFDemo2 {
public static void main(String[] args) {
// 从目标目录下的 raf.dat 文件中读取字节
File file = new File(".\\src\\main\\java\\com\\zhoux\\file\\raf.dat");
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file,"r");
try {
/**
* int read()
* 从文件中读取一个字节, 返回值为 int 类型, 该 int 值对应的二进制的 “低八位” 就是
* 本次读取出来的字节内容, 如果返回的 int 值是 -1 则表示读取到了文件的末尾(EOF)
* EOF: end of file 文件末尾
*/
int n = raf.read();
System.out.println(n);
System.out.println(raf.read());
} catch (IOException e) {
System.out.println("读取失败!");
e.printStackTrace();
}
} catch (FileNotFoundException e) {
System.out.println("执行失败!");
e.printStackTrace();
}finally {
try {
raf.close();
} catch (IOException e) {
System.out.println("关闭失败!");
e.printStackTrace();
}
}
}
}
3、文件的复制操作
/**
* @author taoyi
* @version 1.0
* @date 2021/3/24 17:29
*
* 本类用于测试文件的复制操作
*
*/
public class RAFDemo3 {
public static void main(String[] args) {
RandomAccessFile r = null;
RandomAccessFile w = null;
File file = new File(".\\11.gif");
File file2 = new File(".\\22.gif");
try {
r = new RandomAccessFile(file,"r");
w = new RandomAccessFile(file2,"rw");
/**
* 以读写第一个字节为例
* 原文件内容
* 10011010 00101101 00111101 10100010 10010101.....
* ^^^^^^^^
* d = src.read()后,d的值如下
* nt d:00000000 00000000 00000000 10011010
*
* desc.write(d)后,复制文件内容如下
* 复制文件
* 10011010
*/
int d;
long start = System.currentTimeMillis(); // 获取当前系统时间的毫秒值
try {
while ((d=r.read())!=-1) {
w.write(d); // 向文件中写入一个字节, 写入的是给定的 int 值所对应的二进制的“低八位”
}
long end = System.currentTimeMillis();
System.out.println("复制完成!耗时: "+(end-start)+"ms");
} catch (IOException e) {
System.out.println("写入失败!");
e.printStackTrace();
}
System.out.println("执行完毕!");
} catch (FileNotFoundException e) {
System.out.println("执行失败!");
e.printStackTrace();
}finally {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4、块读写操作
通过提高每次读写的数据量,减少实际读写的次数可以提高读写效率。
RandomAccessFile提供了块读写的方法
读:
int read(byte[] data)
一次性从文件中读取给定的字节数组总长度的字节量并装入到该数组中,返回值表示实际读取
到的字节量.如果返回值为-1则表示EOF.
例如
文件数据(总共6个字节):
11011101 10101101 00110011 11010010 11001101 00111101
块读:
byte数组: byte[] data = new byte[10]; 创建能保存10个字节的数组
int len=0; 表示每次实际读取到的字节量
读取前
data:[00000000,00000000,00000000,00000000]
len:0
len = src.read(data);//一次性从文件中读取4个字节并存入该数组
读取后:
data:[11011101,10101101,00110011,11010010]
len:4
块写操作
void write(byte[] data)
一次性将给定的字节数组中的所有字节写入文件
void write(byte[] data,int offset,int len)
一次性将给定的字节数组中从下标offset处开始的连续len个字节写入文件
例如:
data:[11011101,10101101,00110011,11010010]
desc.write(data);
复制的文件内容:
11011101 10101101 00110011 11010010
代码如下:
/**
* @author taoyi
* @version 1.0
* @date 2021/3/25 9:20
*
* 通过提高每次读写的数据量, 减少实际读写的次数可以提高读写效率
*
*/
public class Copy_Demo2 {
public static void main(String[] args) {
RandomAccessFile src = null;
RandomAccessFile desc = null;
try {
src = new RandomAccessFile(".\\11.gif","r");
desc = new RandomAccessFile(".\\33.gif","rw");
byte[] data = new byte[10*1024];
int len = 0;
long start = System.currentTimeMillis(); // 获取当前系统时间的毫秒值
// 从原文件中一次性读取10KB 数据到data中
while ((len = src.read(data))!=-1){
// 将读取的10KB 数据一次性写入到复制文件中
desc.write(data);
}
long end = System.currentTimeMillis();
System.out.println("复制完成!耗时: "+(end-start)+"ms");
} catch (Exception e) {
System.out.println("操作失败!");
e.printStackTrace();
} finally {
try {
desc.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
src.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}