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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曛丨黯淡浮华 中级黑马   /  2014-12-19 11:47  /  4708 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

缓冲区的作用是,先把数据放着先,等足够多的时候,我再来取,这样效率高  —— 我就拿字节流的缓冲区来说明吧。

  1. public static void copy_1() throws IOException
  2.         {
  3.                 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.mp3"));
  4.                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("3.mp3"));
  5.                
  6.                 int len = 0;
  7.                 while((len = bis.read())!=-1)
  8.                 {
  9.                         bos.write(len);
  10.                 }
  11.                 bis.close();
  12.                 bos.close();
  13.         }
复制代码

我想问的是, BufferedInputStream  查看API 可以了解,它已经有buf ,我不用自己定义, buf是受保护的,
问题1:我没法指向它,这导致我无法给缓冲区定制大小,它是根据机子的性能决定的是吗 ?


不知道大家有印象没,老毕在讲IO流的时候,自己写了一个MyBufferedInputStream  , 它自己定义了个缓冲区,效率比JAVA还要高很多,
问题2: 效率的提高,是根据缓冲区的大小是吗?

然后我突发奇想 , 好像不用老毕那么麻烦的写法,我也能定制一个缓冲区,而且还可以规定它的大小,你们看我下面的代码:
  1. public static void copy_2() throws IOException
  2.         {
  3.                 FileInputStream  fis = new FileInputStream("1.mp3");
  4.                 FileOutputStream fos = new FileOutputStream("4.mp3");

  5.                 byte[] buf = new byte[1024*4];
  6.                 int len = 0;
  7.                 while((len = fis.read(buf))!=-1)
  8.                 {
  9.                         fos.write(buf,0,len);
  10.                 }
  11.                 fis.close();
  12.                 fos.close();
  13.         }
复制代码

实际的运行,通过时间来计算, 效率好像比JAVA的缓冲区还好,
我想知道,我定义的跟自带的缓冲区的区别在于哪里 ~  哪个更为高效 , 为什么 ~ 请指出 !!
  1.                 long start = System.currentTimeMillis();
  2.                 copy_1();
  3.                 long end   = System.currentTimeMillis();
  4.                 System.out.println((end-start)+"毫秒");

  5.                 long start = System.currentTimeMillis();
  6.                 copy_2();
  7.                 long end   = System.currentTimeMillis();
  8.                 System.out.println((end-start)+"毫秒");
复制代码






5 个回复

倒序浏览
大神们, 帖子都沉下去了 ——  没有人来解决吗 TAT
回复 使用道具 举报
会不会Java中buffer是同步的,而自定义的是非同步的,所以时间上自定义的会效率高些。
回复 使用道具 举报
首先,缓冲区是为提高效率而存在的,具体参考装饰者模式。
关于你说的是不是数组定义的越大越好,这个问题老师已经讲过了。
因为虚拟机对内存是有限制的,你定义的数组越大,在内存中开辟的空间就越大。当超过内存大小限制的到时候,就会出错。
所以定义的数组并非越大越好,最好的是通过available()方法定义一个刚刚好的数组,来充当缓冲区。
回复 使用道具 举报
hello_csu 发表于 2014-12-19 21:49
会不会Java中buffer是同步的,而自定义的是非同步的,所以时间上自定义的会效率高些。 ...

  首先感谢您的回答 ~ 不过百度了会, 好像并没有同步的说法 ~ 不过还是谢谢了 ——
回复 使用道具 举报
云兮丶 发表于 2014-12-20 01:03
首先,缓冲区是为提高效率而存在的,具体参考装饰者模式。
关于你说的是不是数组定义的越大越好,这个问题 ...

您好,首先感谢您的回答——

装饰模式我懂,  数组的定义并非越大越好,这个我也知道, 但是1024*4的倍数来说,按理来说应该不大。

老毕确实讲过会超出内存的问题呢, 嘿嘿 —— 不过他说的就是 available()方法, 还说要慎用。

因为数据太大, 一次性装那么多,会引发错误的 ——  

总的来说,还是谢谢你的分析~  
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马