A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 马姗姗 中级黑马   /  2014-1-6 13:53  /  1240 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 马姗姗 于 2014-1-6 21:59 编辑

FileWriter 是使用“流”,直接将数据写入到具体物理设备中,那么为什么write方法后还要flush刷新该流的缓冲?
既然“流”就是缓冲,那么BufferedWriter缓冲有什么不一样吗?BufferedWriter是怎么提高效率的?

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

3 个回复

正序浏览
  1. package cn04;

  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;

  8. /**
  9. * 需求:把d:\\爸爸去哪儿.mp3复制到项目路径下x.mp3(x=1,2,3,4)
  10. *
  11. * @author Administrator
  12. *
  13. *         基本字节流一次读写一个字节:耗时:52194毫秒
  14. *         基本字节流一次读写一个字节数组:耗时:177毫秒
  15. *         高效字节流一次读写一个字节:耗时:27985毫秒
  16. *         高效字节流一次读写一个字节数组:耗时:53毫秒
  17. */
  18. public class copyMp3Test {
  19.         public static void main(String[] args) throws IOException {
  20.                 long start = System.currentTimeMillis();
  21.                 // show1();
  22.                 // show2();
  23.                 // show3();
  24.                 show4();
  25.                 long end = System.currentTimeMillis();
  26.                 System.out.println("耗时:" + (end - start) + "毫秒");
  27.         }

  28.         private static void show4() throws IOException {
  29.                 // 高效字节流一次读写一个字节数组
  30.                 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
  31.                                 "d:\\爸爸去哪儿.mp3"));
  32.                 BufferedOutputStream bos = new BufferedOutputStream(
  33.                                 new FileOutputStream("4.mp3"));
  34.                 byte[] bys = new byte[1024];
  35.                 int len = 0;
  36.                 while ((len = bis.read(bys)) != -1) {
  37.                         bos.write(bys, 0, len);
  38.                         bos.flush();
  39.                 }
  40.                 // 释放资源
  41.                 bos.close();
  42.                 bis.close();

  43.         }

  44.         private static void show3() throws IOException {
  45.                 // 高效字节流一次读写一个字节
  46.                 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
  47.                                 "d:\\爸爸去哪儿.mp3"));
  48.                 BufferedOutputStream bos = new BufferedOutputStream(
  49.                                 new FileOutputStream("3.mp3"));
  50.                 int by = 0;
  51.                 while ((by = bis.read()) != -1) {
  52.                         bos.write(by);
  53.                         bos.flush();
  54.                 }
  55.                 // 释放资源
  56.                 bos.close();
  57.                 bis.close();

  58.         }

  59.         private static void show2() throws IOException {
  60.                 // 基本字节流一次读写一个字节数组
  61.                 FileInputStream fis = new FileInputStream("d:\\爸爸去哪儿.mp3");
  62.                 FileOutputStream fos = new FileOutputStream("2.mp3");
  63.                 byte[] bys = new byte[1024];
  64.                 int len = 0;
  65.                 while ((len = fis.read(bys)) != -1) {
  66.                         fos.write(bys, 0, len);
  67.                         fos.flush();
  68.                 }
  69.                 // 释放资源
  70.                 fos.close();
  71.                 fis.close();
  72.         }

  73.         private static void show1() throws IOException {
  74.                 // 基本字节流一次读写一个字节
  75.                 FileInputStream fis = new FileInputStream("d:\\爸爸去哪儿.mp3");
  76.                 FileOutputStream fos = new FileOutputStream("1.mp3");
  77.                 int by = 0;
  78.                 while ((by = fis.read()) != -1) {
  79.                         fos.write(by);
  80.                         fos.flush();
  81.                 }
  82.                 // 释放资源
  83.                 fos.close();
  84.                 fis.close();
  85.         }
  86. }
  87. BufferedWriter   将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。  可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。  该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。
复制代码

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
同学,首先“流”不一定都带缓冲区的,不能认为“流”就是缓冲。只有字符流,也就是Reader和Writer才带缓冲区的,字节流steam直接就写入、读取,不带缓冲区的。其二,FileWriter既然是字符流,自然是有缓冲区的,查API,FileWriter是OutputStreamWriter的子类,该类是有缓冲区的,实现了flush。
查阅OutputStreamWriter的描述:我们找到这样一段话:
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器

是不是可以这么理解,缓冲是分为两个阶段的,OutputStreamWriter在write 和底层的字节输出之间建立了缓冲,而BufferedWriter 则在调用write之前就建立了缓冲,从而避免了频繁调用write,而是攒够数据一次性的write。恩,我就能理解到这里了,坐等高手全面解答。


评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
write方法并不是直接将数据写入到存储介质中 而是写入到内存中的缓冲区中 使用flush方法后 才会将内存缓冲区中的数据写进存储介质
filewrite写入文件的方式是从源文件中读取一个字节 再向内存写入一个字节
bufferedwriter是从源文件读取一定的字节到字节数组中 当该数组的容量满了以后 才将数组中的数据写入到内存的缓冲区里。
打个比方 这是毕姥爷的教程里的比方:
你i想喝水 饮水机坏了 只能一滴一滴的滴水 如果没有缓冲区 只能饮水机滴一滴 你喝一滴
而有了缓冲区 就相当于拿了个杯子放在饮水机的出水口那 等杯子的水满了 你才去喝杯子里的水

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马