当前位置 : 主页 > 编程语言 > java >

使用IO流复制文件

来源:互联网 收集:自由互联 发布时间:2023-02-04
对文件的复制也是我们工作当中经常会遇到的操作,那么哪种方式效率更快呢,今天来做个测试。 头脑风暴 首先能想到的就是,采用两个数据流:一个用于读取、一个用于写入; IO流

对文件的复制也是我们工作当中经常会遇到的操作,那么哪种方式效率更快呢,今天来做个测试。

使用IO流复制文件_缓存

头脑风暴

  • 首先能想到的就是,采用两个数据流:一个用于读取、一个用于写入;
  • IO流我们可以采用字节流或字符流,但是字符流只适合操作文本文件,然而我们的目标怎么可能只局限在文本文件呢,要复制就能复制所有的文件类型,比如图片、视频、办公文档、压缩文件等等;

因此,必须采用字节流。

1、使用最基础的输入输出字节流

采用文件输入输出字节流,按照字节读取和写入。 为了感知文件的复制效率,增加开始和结束的时间计算。

import java.io.FileInputStream;import java.io.FileOutputStream; public class CopyFile { public static void main(String[] args) { //开始时间 long startTime = System.currentTimeMillis(); try { //声明将文件内容读取到内存的节点流 FileInputStream fis = new FileInputStream("E:/Swagger.pdf"); //声明将内存数据写入到文件的节点流 FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf"); int read = 0; //按字节读取 while ((read = fis.read()) != -1){ //按字节写入 fos.write(read); } //刷新缓存到文件 fos.flush(); fos.close(); fis.close(); }catch (Exception e){ e.printStackTrace(); } //结束时间 long endTime = System.currentTimeMillis(); //耗时 System.out.println((endTime - startTime)); }}

输出:

1410

这种方法虽然可以完成文件复制功能,但是效率低,因为每个字节读取或写入,需要调用大量的磁盘IO操作。

2、在输入输出字节流中加入缓存

依然采用文件输入输出字节流,但此次增加了字节数组作为缓存,增加了一次读取和写入的数据量。

import java.io.FileInputStream;import java.io.FileOutputStream; public class CopyFile { public static void main(String[] args) { long startTime = System.currentTimeMillis(); try { FileInputStream fis = new FileInputStream("E:/Swagger.pdf"); FileOutputStream fos = new FileOutputStream("E:/Swagger_bak.pdf"); //启用缓存 byte[] buf = new byte[1024]; int read = 0; //从文件中一次读取缓存中定义的字节 while ((read = fis.read(buf)) != -1){ //向文件中一次写入缓存中定义的字节数据 fos.write(buf, 0, read); } fos.flush(); fos.close(); fis.close(); }catch (Exception e){ e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println((endTime - startTime)); }}

输出:

5

加入了缓存数组后,减少了磁盘IO操作,按块对源文件数据进行读取,并批量写入,可以看到,文件复制的效率提升非常明显。

需要注意的是:缓存块的大小定义要适中,太小起不到作用,太大会占用过多内存。 定义太大,如果是多任务并行执行,可能会导致内存溢出。

3、不使用缓存,仅使用字节缓冲流拷贝文件

在原先文件输入输出字节流的基础上,仅增加字节缓冲流,不使用缓存。

import java.io.FileInputStream;import java.io.FileOutputStream; public class CopyFile { public static void main(String[] args) { //开始时间 long startTime = System.currentTimeMillis(); try { FileInputStream fis = new FileInputStream("E:/Swagger.pdf"); FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf"); //声明字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream(fis); //声明字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(fos); int read = 0; //将文件内容读取到缓冲流中 while ((read = bis.read()) != -1){ //将文件内容写入到字节缓冲流 bos.write(read); } bos.flush(); bos.close(); bis.close(); }catch (Exception e){ e.printStackTrace(); } //结束时间 long endTime = System.currentTimeMillis(); //耗时 System.out.println((endTime - startTime)); }}

输出:

22

从输出的耗时来看,这种方式的效率,也明显优于单纯的使用字节的节点流来实现文件的拷贝,但是相比缓存方式读取,效率并没有优势。

4、字节缓冲流加缓存,实现文件复制

终极测试来了。

在文件输入输出字节流基础上,同时增加字节缓冲流,及字节数组的缓存。

import java.io.FileInputStream;import java.io.FileOutputStream; public class CopyFile { public static void main(String[] args) { //开始时间 long startTime = System.currentTimeMillis(); try { FileInputStream fis = new FileInputStream("E:/Swagger.pdf"); FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf"); //声明字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream(fis); //声明字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(fos); //声明缓存 byte[] buf = new byte[1024]; int read = 0; //采用缓冲流,读写缓存数据 while ((read = bis.read(buf)) != -1){ bos.write(buf, 0, read); } bos.flush(); bos.close(); bis.close(); }catch (Exception e){ e.printStackTrace(); } //结束时间 long endTime = System.currentTimeMillis(); //耗时 System.out.println((endTime - startTime)); }}

输出:

2

采用这种方式,同时使用的缓冲流和缓存技术,相比前几种实现方式,进一步提升了文件的读写效率,适当增大缓存数组,充分利用内存实现文件的极速复制。

总结:

文件复制的效率依次为:

字节流 < 缓冲流 < 缓存 < 缓冲流+缓存

也能看出,只要能减少磁盘IO操作,效率自然就会提升。

上一篇:Java 反射 (二) Class类
下一篇:没有了
网友评论