IO流四种基本的文件复制方式的复制及速度比较

时间:2021-01-23 17:19:59

先声明,速度慢的占用内存少;速度快的占用内存大。这是“以时间换空间”和"以空间换时间"的不同方式。

第一种:采用FileInputStream字节流的方式,

即: FileInputStream fis=new FileInputStream(“……”);
Fis.read();
这种方式每次只获取一个字节的数据,而要复制的数据变大时,就要增加大量的循环次数,才可以把所有数据复制完,——速度是相当的慢,平时开发今本不用这种复制方式。
第二种:采用FileInputStream + byte[] 的方式,
及FileInputStream fis=new FileInputStream(“……”);
Byte[] b=new byte[1024];//一般情况下都是使用1024长度的                                                                        //数组

Fis.read(b);
这种方式,是将读取的数据先存储在字节数据中,然后再对数据进行输入,输出操作,大大降低了循环次数,并且往数组中存储数据是相对比较快的操作。
第三种
采用字符流缓冲区对象复制文件
即:BufferedInputStream+FileInputStream读取数据源
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(“……”));
Bis.read();
采用字符流缓冲区对象,是专门解决字节流读取写入数据慢的问题。
第四种:
及在第三种的方式上采用读取数据存入 byte[] 中。

写数据 和读数据一致。。。


下面是四种方法:及每种方法的复制速度比较。
  1. /*
  2. * 进行文件复制方法   及效率对比
  3. * 四种方式
  4. *   1. 字节流读写单个字节  135095
  5. *   2. 字节流读写字节数组  208   推荐
  6. *   3. 缓冲区读写单个字节  1187
  7. *   4. 缓冲区读写字节数组  90    强烈推荐
  8. *   我们复制一个25M大小的视屏文件1.avi
  9. *   数据源: c:\\1.avi
  10. *   数据目的: d:\\1.avi
  11. *   
  12. *   自己的复制功能,比固体要快,比Windows也要快
  13. *   为什么:
  14. *     流底层也是找Windows读写
  15. *     固态中,复制文件,依赖Windows
  16. *     复制,实现很多功能:
  17. *        目的,够不够装文件
  18. *        判断用户有没有复制权限,粘贴权限
  19. *   
  20. */
  21. import java.io.*;
  22. public class CopyFile_Test {
  23.         public static void main(String[] args) {
  24.                 // 测试效率,采用毫秒值计算
  25.                 long start = System.currentTimeMillis();
  26.                 copy_4();
  27.                 long end = System.currentTimeMillis();
  28.                 System.out.println(end - start);
  29.         }
  30.         /*
  31.          * 4. 缓冲区读写字节数组
  32.          */
  33.         public static void copy_4(){
  34.                 // 创建2个缓冲区流的变量,=null
  35.                 BufferedInputStream bis = null;
  36.                 BufferedOutputStream bos = null;
  37.                 try {
  38.                         // 创建字节流缓冲区对象,传递字节流
  39.                         bis = new BufferedInputStream(
  40.                                         new FileInputStream("c:\\m.exe"));

  41.                         // 创建字节输出流缓冲区对象,传递字节输出流
  42.                         bos = new BufferedOutputStream(
  43.                                         new FileOutputStream("d:\\m.exe"));

  44.                         // 读写字节数组
  45. /*
  46. *当数组长度,在一定范围内长度更大的时候,复制速度会更快,
  47. *但如果过长,系统在为bytes分配数组的时间就会很长,反而降低了复         *制速度.所以不能使用太长的数组.
  48. */
  49.                         byte[] bytes = new byte[1024];

  50.                         int len = 0;
  51.                         while ((len = bis.read(bytes)) != -1) {
  52.                                 bos.write(bytes,0,len);
  53.                         }
  54.                 } catch (IOException ex) {
  55.                         throw new RuntimeException("文件复制失败");
  56.                 } finally {
  57.                         MyCloseStream.close(bis, bos);
  58.                 }        
  59.         }

  60.         /*
  61.          * 3. 缓冲区读写单个字节
  62.          */
  63.         public static void copy_3() {
  64.                 // 创建2个缓冲区流的变量,=null
  65.                 BufferedInputStream bis = null;
  66.                 BufferedOutputStream bos = null;
  67.                 try {
  68.                         // 创建字节流缓冲区对象,传递字节流
  69.                         bis = new BufferedInputStream(
  70.                                         new FileInputStream("c:\\1.avi"));

  71.                         // 创建字节输出流缓冲区对象,传递字节输出流
  72.                         bos = new BufferedOutputStream(
  73.                                         new FileOutputStream("d:\\1.avi"));

  74.                         // 读写单个字节
  75.                         int len = 0;
  76.                         while ((len = bis.read()) != -1) {
  77.                                 bos.write(len);
  78.                         }
  79.                 } catch (IOException ex) {
  80.                         throw new RuntimeException("文件复制失败");
  81.                 } finally {
  82.                         MyCloseStream.close(bis, bos);
  83.                 }
  84.         }

  85.         /*
  86.          * 2. 字节流读写字节数组
  87.          */
  88.         public static void copy_2() {
  89.                 FileInputStream fis = null;
  90.                 FileOutputStream fos = null;
  91.                 try {
  92.                         fis = new FileInputStream("c:\\1.avi");
  93.                         fos = new FileOutputStream("d:\\1.avi");
  94.                         // 定义字节数组,长度1024整数倍
  95.                         byte[] bytes = new byte[1024];
  96.                         int len = 0;
  97.                         while ((len = fis.read(bytes)) != -1) {
  98.                                 // fos流写字节数组
  99.                                 fos.write(bytes, 0, len);
  100.                         }
  101.                 } catch (IOException ex) {
  102.                         ex.printStackTrace();
  103.                         throw new RuntimeException("复制失败");
  104.                 } finally {
  105.                         // 调用工具类close方法
  106.                         MyCloseStream.close(fis, fos);
  107.                 }
  108.         }

  109.         /*
  110.          * 1. 字节流读写单个字节
  111.          */
  112.         public static void copy_1() {
  113.                 // 声明2个流对象,=null
  114.                 FileInputStream fis = null;
  115.                 FileOutputStream fos = null;
  116.                 try {
  117.                         // 创建2个流对象,new
  118.                         fis = new FileInputStream("c:\\1.avi");
  119.                         fos = new FileOutputStream("d:\\1.avi");
  120.                         // fis读取1个字节,fos写1个字节
  121.                         int len = 0;
  122.                         while ((len = fis.read()) != -1) {
  123.                                 fos.write(len);
  124.                         }
  125.                 } catch (IOException ex) {
  126.                         ex.printStackTrace();
  127.                         throw new RuntimeException("复制失败");
  128.                 } finally {
  129.                         MyCloseStream.close(fis, fos);
  130.                 }
  131.         }
  132. }



  133. MyCloseStream.java

  134. /*  关闭方法close的细节
  135. *  单独的close方法,定义一套自己的try catch处理
  136. *  保证所有的close都会执行到
  137. */
  138. import java.io.*;
  139. public class CopyFile {
  140.         public static void main(String[] args) {
  141.                 //声明2个流对象,=null
  142.                 FileInputStream fis = null;
  143.                 FileOutputStream fos = null;
  144.                 try{
  145.                         //创建2个流对象,new
  146.                         fis = new FileInputStream("c:\\t.jpg");
  147.                         fos = new FileOutputStream("d:\\t.jpg");
  148.                         //fis读取1个字节,fos写1个字节
  149.                         int len = 0 ;
  150.                         while((len = fis.read())!=-1){
  151.                                 fos.write(len);
  152.                         }
  153.                 }catch(IOException ex){
  154.                         ex.printStackTrace();
  155.                         throw new RuntimeException("复制失败");
  156.                 }finally{
  157.                         try{
  158.                                 if(fos!=null)
  159.                                         fos.close();
  160.                         }catch(IOException ex){
  161.                                 throw new RuntimeException("释放资源失败");
  162.                         }finally{
  163.                                 try{
  164.                                         if(fis!=null)
  165.                                                 fis.close();
  166.                                 }catch(IOException ex){
  167.                                         throw new RuntimeException("释放资源失败");
  168.                                 }
  169.                         }
  170.                 }
  171.         }
  172. }
复制代码


希望对要学IO的有一丁点帮助。