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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 秦斌 于 2013-1-3 10:51 编辑

准备文件jdk-7u9-windows-x64.exe (94,398,944字节)
代码1,不用Buffered:
  1. import java.io.*;
  2. class CopyTest{
  3.         public static void main(String[] args)throws IOException{
  4.                 long start = System.currentTimeMillis();
  5.                 FileInputStream  fis = new FileInputStream("D:\\jdk-7u9-windows-x64.exe");
  6.                 FileOutputStream fos = new FileOutputStream("D:\\jdk-7u9-windows-x64-2.exe");
  7. //可将下面的byte数组该为1024或者1024*10或者1024*1024*10
  8.                 byte[] b = new byte[1024*1024];
  9.                 int len;
  10.                 while ((len = fis.read(b))!=-1){
  11.                         fos.write(b,0,len);
  12.                 }
  13.                 fis.close();
  14.                 fos.close();
  15.                 long end = System.currentTimeMillis();
  16.                 System.out.println((end-start)+"毫秒");
  17.         }
  18. }
复制代码
代码2,使用buffered:
  1. import java.io.*;
  2. class BufferedCopyTest{
  3.         public static void main(String[] args)throws IOException{
  4.                 long start = System.currentTimeMillis();
  5. //可使用另一个构造函数设置缓冲大小
  6. //可将下语句中的1024*1024改为1024或1024*10或1024*1024*10
  7. //BufferedInputStream buffis = new BufferedInputStream (new FileInputStream("D:\\jdk-7u9-windows-x64.exe"),1024*1024);
  8.                 BufferedInputStream buffis =  new BufferedInputStream (new FileInputStream("D:\\jdk-7u9-windows-x64.exe"));
  9. //可将下语句中的1024*1024改为1024或1024*10或1024*1024*10
  10. //BufferedOutputStream buffos = new BufferedOutputStream(new FileOutputStream("D:\\jdk-7u9-windows-x64-2.exe"));
  11.                 BufferedOutputStream buffos = new BufferedOutputStream(new FileOutputStream("D:\\jdk-7u9-windows-x64-2.exe"));
  12.                 int num;
  13.                 while ((num = buffis.read())!=-1){
  14.                         buffos.write(num);
  15.                 }
  16.                 buffis.close();
  17.                 buffos.close();
  18.                 long end = System.currentTimeMillis();
  19.                 System.out.println((end-start)+"毫秒");
  20.         }
  21. }
复制代码
代码1,居然只用时0.2秒左右。
代码2,大概需要不到4秒的时间。

问题来了:
1、带Buffered的居然还慢些,这是为啥?
2、代码1,居然超出了硬盘的物理极限,这是为啥?




评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

8 个回复

正序浏览
buffered的流肯定没有自己提供缓存快  你不看看 buffered那个类除了提供缓存外还有多少无关的代码这些代码都是需要消费时间滴。。
就跟你用fileInputStream读取一个文件花费的时间大 还是你用fileInputStream读取一个文件并且又for循环计算1加到1000说费的时间多。。。
回复 使用道具 举报
清水 中级黑马 2012-12-30 18:57:56
8#
0.2秒搞定了90多M的文件。 转速7200的硬盘速度也就是60M左右吧。
回复 使用道具 举报
带Buffered的,它一开始是要一些时间来进行缓冲,一开始是会慢些,但是操作那些大文件,它的性能就能体现出来。
对于“代码1,居然超出了硬盘的物理极限,这是为啥?”,JVM有它自己的内存大小,估计是是你的代码中有地方占用内存太大了
回复 使用道具 举报
对于Buffered慢,我的一个编程的朋友是这样理解的。不用Buffered的时候,一次write了1024*1024,循环的次数为文件的M数。使用了Buffered,每次只写1个,时间大多都耗费在while循环上面了。循环次数是文件的字节数。
回复 使用道具 举报
个人判断 用BufferedInputStream当然会更慢,BufferedInputStream是一个线程安全的缓冲输入流,线程安全牺牲的是性能,buffered需要考虑线程安全问题,所以运行速度更慢。
回复 使用道具 举报
使用缓冲区,他需要一些时间来缓冲,缓冲区是给那些大文件用的,小文件的话,可以不用缓冲区
回复 使用道具 举报
改成 byte[] b = new byte[1024*8]; 还是快些呢,不信你试试。
回复 使用道具 举报
记得buf自带的缓冲区是8k的,楼主代码1设置的缓冲区是1m,读取1m后写入,显然是代码1更快。
对于小文件可是设置缓冲区长度为fis.available(),也就是文件的长度应该是读取最快的。不过不建议使用,大文件可能会堆内存溢出。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马