缓冲流
对于节点流FileReader、FileWriter以及FileInputStream、FileOutputStream,真实开发场景中很少直接用,一般都会配合使用处理流(如缓冲流),来提高文件的处理效率。
缓冲流
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream、BufferedOutputStream
- BufferedReader、BufferedWriter
文件复制
修改之前使用字节流实现的文件复制功能,该用缓冲流。然后,测试下效率高了多少。
public class FileUtil {
public static void copy (File src, File dst) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dst);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) > -1) {
// 这里不需要flush操作,因为write方法里已经用了flush操作。
bos.write(bytes, 0, len);
}
} catch (IOException e) {
throw e;
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
}
}
}
注意,应该先关闭外层流,再关闭内存流。(形象比喻:穿衣先穿内衣再穿外衣,脱衣先脱外衣再脱内衣)。另外,只需要关闭最外层流,内存流就会自动关闭。
测试代码如下:
File src = new File("C:\迅雷下载\海贼王-480.mp4");
File dst = new File("dir/1.mp4");
long start = System.currentTimeMillis();
try {
FileUtil.copy(src, dst);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() - start);
效率从1857毫秒变成了379.提升的效率非常明显。
图片加密与解密
package com.studyjava.gwx.IO;
import java.io.*;
/**
* @author monkeykingGWX
* email 704835519@qq.com
* created 2021-03-13 19:46
*/
public class FileUtil {
……
// 文件加密
public static void encrypt (File src, File dst) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dst);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) > -1) {
for (int i = 0; i < len; i ++) {
bytes[i] = (byte) (bytes[i] ^ 5);
}
// 这里不需要flush操作,因为write方法里已经用了flush操作。
bos.write(bytes, 0, len);
}
} catch (IOException e) {
throw e;
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
}
}
// 文件解密
public static void decrypt (File src, File dst) throws IOException {
encrypt(src, dst);
}
}
测试代码如下
// 图片加密
File src = new File("dir/1.jpg");
File dst = new File("dir/encrypt.jpg");
try {
FileUtil.encrypt(src, dst);
} catch (IOException e) {
e.printStackTrace();
}
// 图片解密
try {
FileUtil.decrypt(dst, new File("dir/decrypt.jpg"));
} catch (IOException e) {
e.printStackTrace();
}