上回说到,Java 常见流对象——文件字节流(缓存),尝试了两种用 byte[] 数组来进行缓存提高读写效率的方法。今天来说说如何用字节缓存流来进行图片的复制:
核心代码讲解
流程都是一样的: IO流实例化——读——写——刷新——关闭流。
- 先实例化一个空的文件对象,然后再把这个 new 好的作为整体,传入到 BufferedInputStream 和 BufferedOutputStream 中去;
- 在 while 的判断对象改为缓存流对象的 read() 方法;
- while 循环内,只要没读到最后,就不停地调 .write();
- 循环结束后,一次性地刷新一下 .flush();
- 依次关闭流。
关闭细节
- 关于处理流与节点流
缓存流是一种处理流,处理流就是在节点流外面包裹的(装饰的)一层流。所以关闭的时候要先关处理流,再关一开始的 fis 流。如果写的时候,把 fis 和 fos 对应的new FileInputSteam和 new FileOutputStream 都放在了 bis 和 bos 里面,关闭的时候只关处理流,节点流也会被关闭: 以 bos 为例,在 .close() 上进行源码的追踪:
通过这里的 out 可以跳转到 OutputSteam 这里:
说明确实对输入流这个节点流也进行了关闭。
- 关于输入输出流:
如果从输入输出的角度来看,先有输出,后有输入,因此要先关闭输出流,再关闭输入流。
代码
static void bufferedFS() { FileInputStream fis = null; FileOutputStream fos = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { fis = new FileInputStream("/Users/fang/Images/题目.png"); bis = new BufferedInputStream(fis); fos = new FileOutputStream("/Users/fang/Images/题目 ou;); bos = new BufferedOutputStream(fos); int temp = 0; while((temp = bis.read())!=-1) { bos.write(temp); } bos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { // 后开先关 bos.close(); bis.close(); (); (); // if (bis!=null) { // bis.close(); // } // if (fis!=null) { // (); // } // if (bos!=null) { // bos.close(); // } // if (fos!=null) { // (); // } } catch (IOException e) { e.printStackTrace(); } } } 复制代码
运行结果
可以发现,和前面两种用法的效率差别不大。