JavaIO流中对数据的操作尤为重要,掌握了基本的拷贝操作,才能将各种数据源的操作联系起来。

  先来看看对文件夹的拷贝吧:

 1 /**
 2  * 利用递归实现文件夹的拷贝操作
 3  * 分析:判断
 4  *     是文件:调用拷贝文件的方法fileCopy(...)
 5  *     是文件夹:创建文件夹,并使用递归实现子文件夹/子文件的判断及操作
 6  * @param src:要拷贝的文件夹源头
 7  * @param dest:要拷贝到的文件夹源头
 8  */
 9 public static void dirCopy(File src,File dest) {
10     if(src.isFile()) { //是文件
11         fileCopy(src, dest);
12     }else { //是文件夹
13         dest.mkdirs();
14         for(File subSrc:src.listFiles()) { //遍历子文件夹/子文件
15             dirCopy(subSrc, new File(dest,subSrc.getName()));
16         }
17     }
18 }

  对文件的拷贝,我们可以这样写:

 1 /**
 2  * 实现文件的拷贝
 3  *     输入流读取的同时输出流进行写出
 4  * @param src:要拷贝的文件源头
 5  * @param dest:要拷贝到的文件源头
 6  */
 7 public static void fileCopy(File src,File dest) {
 8     //1.创建源
 9     //2.选择流
10     InputStream is = null;
11     OutputStream os = null;
12     try {
13         is = new FileInputStream(src);
14         os = new FileOutputStream(dest);
15         //3.操作:分段读取并写出
16         int len; //接收长度
17         byte[] flush = new byte[1024]; //缓冲容器,一次读写1k
18         while((len=is.read(flush))!=-1) {
19             os.write(flush, 0, len);
20         }
21         os.flush(); //写完手动刷新,避免数据在缓冲容器中(当然当流关闭时会自动刷新)
22     }catch(FileNotFoundException e) {
23         e.printStackTrace();
24     }catch(IOException e) {
25         e.printStackTrace();
26     }finally {
27         //4.关闭流,分别关闭,先打开的后关闭
28         try {
29             if(os!=null) {    //判断是否为空,避免空指针异常
30                 os.close();
31             }
32         }catch(IOException e) {
33             e.printStackTrace();
34         }
35         try {
36             if(is!=null) { //判断是否为空,避免空指针异常
37                 is.close();
38             }
39         }catch(IOException e) {
40             e.printStackTrace();
41         }
42     }
43 }

  以上代码只能实现对文件的拷贝操作,当然适合于拷贝任何格式的数据文件,包括视频、音频、图片等等。但是如果我想将一张图片拷贝到字节数组中呢(这里的字节数组相当于内存),也就是说从文件到字节数组,或着是从字节数组到文件。那么以上代码就具有局限性了,也不易于扩展,来看以下代码:

 1 /**
 2  * 对接流
 3  * @param is:输入流
 4  * @param os:输出流
 5  */
 6 public static void copy(InputStream is,OutputStream os) {
 7     //1.创建源
 8     //2.选择流
 9     try {
10         //3.操作
11         byte[] flush = new byte[1024]; //缓冲容器
12         int len; //接收长度
13         while((len=is.read(flush))!=-1) {
14             os.write(flush, 0, len);
15         }
16         os.flush();
17     }catch(FileNotFoundException e) {
18         e.printStackTrace();
19     }catch(IOException e) {
20         e.printStackTrace();
21     }finally {
22         try {
23             if(os!=null) {
24                 os.close();
25             }
26         }catch(IOException e) {
27             e.printStackTrace();
28         }
29         try {
30             if(is!=null) {
31                 is.close();
32             }
33         }catch(IOException e) {
34             e.printStackTrace();
35         }
36     }
37 }

  嗯,这样就可以实现以上要求了,但是我们发现:关闭资源的操作一直在,而且都一样,我们可以封装一下,这样在finally中就可以直接调用了。

 1 /**
 2  * 关闭的方法
 3  * @param is:输入流
 4  * @param os:输出流
 5  */
 6 public static void close(InputStream is,OutputStream os) {
 7     try {
 8         if(os!=null) {
 9             os.close();
10         }
11     }catch(IOException e) {
12         e.printStackTrace();
13     }
14     try {
15         if(is!=null) {
16             is.close();
17         }
18     }catch(IOException e) {
19         e.printStackTrace();
20     }
21 }

  好了,看看封装的代码,幸亏只有两个流,要是流很多咋办,形参太多,但是我们发现输入流InputStream和输出流OutputStream都实现了同一个接口:Closeable。嗯,这样,我们可以试试JDK1.5的新特性:可变参数。

 1 /**
 2  * 封装的关闭方法
 3  * @param ios:要关闭的流
 4  */
 5 public static void close(Closeable... ios) {
 6     for(Closeable io:ios) {
 7         try {
 8             if(io!=null) {
 9                 io.close();
10             }
11         }catch(IOException e) {
12             e.printStackTrace();
13         }
14     }
15 }

  现在看似完美了,但我还不太满意,有时候,我觉得手动关闭资源太麻烦了。别急,来看看JDK1.7的新特性:try...with...resources(自动关闭资源)。

 1 /**
 2  * JDK1.7之后的新特性 try...with...resources:自动关闭资源
 3  * 文件的拷贝
 4  * @param srcPath:要拷贝的源头
 5  * @param destPath:要拷贝到的目的地
 6  */
 7 public static void copy1(String srcPath,String destPath) {
 8     //1.创建源
 9     File src = new File(srcPath);
10     File dest = new File(destPath);
11     //2.选择流
12     try(InputStream is = new FileInputStream(src);
13         OutputStream os = new FileOutputStream(dest)) {
14         //3.操作
15         byte[] flush = new byte[1024]; //缓冲容器
16         int len; //接收长度
17         while((len=is.read(flush))!=-1) {
18             os.write(flush, 0, len);
19         }
20         os.flush();
21     }catch(FileNotFoundException e) {
22         e.printStackTrace();
23     }catch(IOException e) {
24         e.printStackTrace();
25     }
26 }

  大家发现:try里面写的好繁琐,别急,看看JDK1.9的改进版(不过要求你所要关闭的资源是final或等效于final的变量)。

 1 /**
 2  * JDK1.9之后对 try...with...resources的改进
 3  * 对接流
 4  * @param is:输入流
 5  * @param os:输出流
 6  */
 7 public static void copy2(InputStream is,OutputStream os) {
 8     //1.创建源
 9     //2.选择流
10     try(is;os) {
11         //3.操作
12         byte[] flush = new byte[1024]; //缓冲容器
13         int len; //接收长度
14         while((len=is.read(flush))!=-1) {
15             os.write(flush, 0, len);
16         }
17         os.flush();
18     }catch(FileNotFoundException e) {
19         e.printStackTrace();
20     }catch(IOException e) {
21         e.printStackTrace();
22     }
23 }

  哈哈,看上去是不是简洁很多。对的,随着JDK的新版本发布,越来越多的新技术,也使得代码看起来越简洁,不过对我们的要求也只会越来越高。前段时间JDK12已经出来了,还没用,不过我相信肯定会有好多的新特性,期待,也看好Java,加油。

转载于:https://www.cnblogs.com/wuyongji/p/10597200.html

JavaIO流中的拷贝相关推荐

  1. 总结JAVA----IO流中的字节流

    对于IO流中字节流的总结 字节流的概念 由于应用程序,经常需要和文件打交道,所以Inputstream专门提供了读写文件的子类:FileInputStream和FileOutputStream类,如果 ...

  2. 【JavaIO流】JavaIO中的常用处理流

    JavaIO中的常用处理流 在前面,我们了解了有关JavaIO流基础的使用,其中对于IO流来说最基础的四大基类就是InputStream.OutputStream.Reader.Writer.而我们对 ...

  3. JavaIO流_下(NIO.2中Path、Paths、Files类的使用)

    NIO.2中Path.Paths.Files类的使用 Java NIO 概述 ​ Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO AP ...

  4. java-IO流(5)-IO流中的设计模式(装饰器模式和适配器模式)的介绍

    目录 1装饰器模式 1.1定义 1.2代码实现 1.3装饰器特点 1.4装饰器在IO流中的使用 2配适器模式 2.1Adapter适配器 2.2代码实例 2.3适配器特点 2.4适配器优缺点 2.5适 ...

  5. Java------IO流与异常处理机制 详解

    IO流与异常处理机制 File类 File类的每一个实例可以表示硬盘(文件系统)中的一个文件或目录(实际上表示的是一个抽象路径) 使用File可以做到: 1:访问其表示的文件或目录的属性信息,例如:名 ...

  6. javaio流_万字长文+思维导图帮你梳理 Java IO 流,还学不会你来打我(值得收藏)...

    前言 在上一篇的文章获取不错的浏览量后,继续加更的念头一直徘徊在心中,本来是想花段时间深入学习tomcat的,可是tomcat的源码中就有至关重要的NIO,于是得先整一下NIO,但是NIO的基础是BI ...

  7. javaio流层次结构_流的多层次分组

    javaio流层次结构 1.简介 使用Java 8流,可以很容易地根据不同的标准对对象集合进行分组. 在这篇文章中,我们将看到如何从简单的单级分组到更复杂的,涉及多个级分组的分组. 我们将使用两个类来 ...

  8. Java从入门到精通十一(javaIO流)

    Java从入门到精通十一(javaIO流) IO引入 字节流和字符流(一些说明) 字节流没有用到缓冲区并不是没有用到内存 为什么输入流是读数据,而输出流是写数据? 字节流说明 字节输入流读数据的方法 ...

  9. 解决关于java的IO流进行文件拷贝时拒绝访问的问题

    解决关于java的IO流进行文件拷贝时拒绝访问的问题 1.在学习java IO流的时候,想进行文件的自动拷贝功能,我的代码是在idea中编写的,编写没有报红,但是运行时却出现了java.io.File ...

最新文章

  1. 什么是外函数,什么是内函数?闭包(Closure)是什么?说说你对闭包(Closure)的理解?
  2. 在centos上搭建svn服务器
  3. 《系统集成项目管理工程师》必背100个知识点-47质量保证人员(QA)的主要工作...
  4. best introduction to camera calibration
  5. 【网摘阅读】舒迅:产品经理必读的九步法
  6. html设置点击事件相同,html有多个类名相同的div,如何给每个div绑定click事件并区分?...
  7. vertx rest 跨域_在基于简单Vertx Rest的应用程序上为REST资源设置基本响应HTTP标头...
  8. 微软官方工具_时隔20年再出发!微软官方推出最强Windows工具集
  9. 关于python安装scipy模块的问题
  10. 「leetcode」110.平衡二叉树
  11. 转【es中数据节点和主机】
  12. Linux下的帮助命令
  13. IEC 60068-2 规范介绍
  14. win7 64位系统加载dsoframer.ocx问题解决方法
  15. 手机评论文本挖掘与数据分析(Python)
  16. html5 微信签到墙,3D签到墙 webgl示例源码(three.js)
  17. 5G基站到底长啥样?和4G有啥区别?
  18. 【HDR学习】HDR视频相关知识讲解(一)
  19. 微信企业号之获取所有部门列表
  20. 安卓高通机型的基带移植 修改 编译的相关 增加信号 支持5G等【二】

热门文章

  1. oracle ebs wsh picking batch,ebs 11i 订单相关表结构学习及销售到出仓所经历的表
  2. python with关键字_python中用with关键字来实现上下文管理器.
  3. python将十进制转为二进制_如何用Python将十进制数字转为二进制,以及将二进制转为十六进制?...
  4. 4位数的水仙花c语言,C语言程序设计100例之(4):水仙花数
  5. go redis 序列化_求求你不要手写Redis缓存
  6. RS232电平 RS485电平 RS422电平 TTL电平
  7. python重复输入字符串a三次_8道Python基础面试练习题
  8. kext updater使用方法_语言清晰度测量方法的前世今生
  9. python实现链表的删除_干货||链表的技巧和算法总结
  10. rt-n18u usb3.0 linux ex,2.4G王者 华硕 AUSU RT-N18U 评测