【Java】使用文件字节输入/输出流复制文件、使用字节缓冲输入/输出流复制文件的区别

  首先我们来对比一下文件字节输入流字节缓冲输入流的read方法,可以看到两者的read方法的都继承自InputStream类,且read(bytes[ ] b)方法都没有被子类重写,所以代码执行的效率理论上没有区别。

  再来对比文件字节输出流字节缓冲输出流的write方法,可以看到有所不同:
  文件字节输出流的write(bytes[ ] b)是将字节数组中的数据直接写入到此文件输出流,不经过缓冲区;字节缓冲输出流会给文件字节输出流增加一个缓冲区,提高文件字节输出流的写入效率,然后通过flush方法,将缓冲区中的数据刷新到文件中。

  综上所述,使用文件字节输入/输出流复制文件、使用字节缓冲输入/输出流复制文件的区别就在于:
  两者在输入上都经过缓冲区(缓冲数组);但是在输出上,文件字节输出流不经过缓冲区,字节缓冲输出流经过缓冲区。所以理论上,使用字节缓冲输入/输出流进行文件复制的效率要高于使用文件字节输入/输出流。

代码示例

  使用文件字节输入/输出流复制一张图片,耗时60毫秒左右。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("C:\\1.jpg");
FileOutputStream fos = new FileOutputStream("D:\\1.jpg");
//一次读取多个字节,写入多个字节的方式(使用数组缓冲)
byte[] bytes = new byte[1024];//对于较大的文件,适当调整为1024的整数倍能大幅提高复制效率
int len = 0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);//len保证写入的是字节数组中的有效字节(当前循环中)
}
fos.close();
fis.close();
long e = System.currentTimeMillis();
System.out.println(e-s);
}

  使用字节缓冲输入/输出流复制同一张图片,耗时20毫秒左右。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\1.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\1.jpg"));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes);
}
bos.close();
bis.close();
long e = System.currentTimeMillis();
System.out.println(e-s);
}
————————— 本文结束 感谢您的阅读 —————————
谢谢你请我喝咖啡ლↂ‿‿ↂლ(支付宝扫一扫即可领红包, 消费时可抵现! 你省钱, 我赚钱, 多谢支持~)