FileInputStream 与 BufferedInputStream 的区别和效率对比

FileInputStream与BufferedInputStream区别:

BufferedInputStream是套在某个其他的InputStream外,起着缓存的功能,用来改善里面那个InputStream的性能(如果可能的话),它自己不能脱离里面那个单独存在。FileInputStream是读取一个文件来作InputStream。所以你可以把BufferedInputStream套在FileInputStream外,来改善FileInputStream的性能。 

FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。),因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高,且FileInputStream对象的read方法会出现阻塞;BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。BufferedOutputStream和FileOutputStream同理,差异更明显一些。  

  

FileInputStream与FileReader区别:
FileInputStream是字节流,FileReader是字符流,用字节流读取中文的时候,可能会出现乱码,而用字符流则不会出现乱码,而且用字符流读取的速度比字节流要快;

ObjectOutputStream与ByteArrayOutputStream的区别:
ObjectOutputStream可以将java对象写入outputstream流中(序列化),然后进行持久化,此对象必须是实现了java.io.Serializable 接口;

ByteArrayOutputStream是将数据写入byte数组中;

简单说一下阻塞:

假设一个文件的长度是100个字节,要将之读取到内存中,再假设您每次只读取10个字节,那么读完整个文件是不是读取10次的呀?
假设老板让你完成100件事情,老板说,你每天只完成10件就可以了,难道你非得等到第十天才完成第100件事情吗?有一天您在中午下班前就完成了10件事情,下午您不妨多干一点,那么也许在第9天的时候就完成了100件事情。
同理,BufferedInputStream有可能会读取比您规定的更多的东西到内存,以减少访问IO的次数。简单点说阻塞就是你有能力办某一件事,但是,迫于其他压力或什么只能干等着每次只干固定的事,会浪费资源从而造成阻塞


FileInputStream 与 BufferedInputStream 的效率对比:

我们采用文件复制来做效率对比的实验。

  在FileOperator类的copyWithFileStream方法实现了使用FileInputStream和FileOutputStream复制文件,copyWithBufferedStream方法实现了使用BufferedInputStream和BufferedOutputStream复制文件。

/* 
  * Copyright (c) 2014 xxx.com. All Rights Reserved. 
  */  
  package utils;  
  import java.io.BufferedInputStream;  
  import java.io.BufferedOutputStream;  
  import java.io.File;  
  import java.io.FileInputStream;  
  import java.io.FileNotFoundException;  
  import java.io.FileOutputStream;  
  import java.io.IOException;  
  /** 
  * @author ham.hog created on 2014 14-2-12 下午2:58 
  * @version 0 
  */  
  public class FileOperator {  
  /** buffer size in bytes */  
  final static int BUFFER_SIZE = 100;  
  /** 
  * copy file using FileInputStream & FileOutputStream 
  * @param src copy from 
  * @param dest copy to 
  * @return; 
  */  
  public static void copyWithFileStream(File src, File dest){  
  FileInputStream input = null;  
  FileOutputStream output = null;  
  try {  
  input = new FileInputStream(src);  
  output = new FileOutputStream(dest);  
  byte[] buffer = new byte[BUFFER_SIZE];  
  int copySize;  
  while ((copySize = input.read(buffer)) > 0){  
  output.write(buffer, 0, copySize);  
  output.flush();  
  }  
  } catch (FileNotFoundException e) {  
  e.printStackTrace();  
  } catch (IOException e) {  
  e.printStackTrace();  
  } finally {  
  try {  
  input.close();  
  output.close();  
  } catch (IOException e) {  
  e.printStackTrace();  
  }  
  }  
  }  
  /** 
  * copy file using BufferedInputStream & BufferedOutputStream 
  * @param src copy from file 
  * @param dest copy to file 
  * @return; 
  */  
  public static void copyWithBufferedStream(File src, File dest){  
  BufferedInputStream bufferedInput = null;  
  BufferedOutputStream bufferedOutput = null;  
  try {  
  bufferedInput = new BufferedInputStream(new FileInputStream(src));  
  bufferedOutput = new BufferedOutputStream(new FileOutputStream(dest));  
  byte[] buffer = new byte[BUFFER_SIZE];  
    int copySize;  
  while ((copySize = bufferedInput.read(buffer)) > 0){  
  bufferedOutput.write(buffer, 0, copySize);  
  }  
  } catch (FileNotFoundException e) {  
  e.printStackTrace();  
  } catch (IOException e) {  
  e.printStackTrace();  
  } finally {  
  try {  
  bufferedInput.close();  
  bufferedOutput.close();  
  } catch (IOException e) {  
  e.printStackTrace();  
  }  
  }  
  }  
  }  
  class FileOperatorTest{  
  public static void main(String args[]){  
  File src = new File("test.txt");  
  File dest = new File("copyTest.txt");  
  try {  
  if (!dest.exists()){  
  dest.createNewFile();  
  }  
  } catch (IOException e) {  
  e.printStackTrace();  
  }  
  //test copy using FileStream  
  int startTime = System.currentTimeMillis();  
  FileOperator.copyWithFileStream(src, dest);  
  int endTime = System.currentTimeMillis();  
  System.out.println("Copy file using FileStream takes : " + (endTime - startTime) + " ms.");  
  //test copy using BufferedStream  
  startTime = System.currentTimeMillis();  
  FileOperator.copyWithBufferedStream(src, dest);  
  endTime = System.currentTimeMillis();  
  System.out.println("Copy file using BufferedStream takes : " + (endTime - startTime) + " ms.");  
  }  
  }  


运行结果:
  测试文件大小约为900M,以下是在设定BUFFER_SIZE为不同值时的一次执行结果:
  BUFFER_SIZE = 100
  Copy file using FileStream takes: 42680 ms.
  Copy file using BufferedStream takes: 2407 ms.
  BUFFER_SIZE = 8192
  Copy file using FileStream takes: 1689 ms.
  Copy file using BufferedStream takes: 1654 ms.
  BUFFER_SIZE = 1000000
  Copy file using FileStream takes: 957 ms.
  Copy file using BufferedStream takes: 929 ms.
对时间效率差异的解释:
  BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
  因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
  BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。
  BufferedOutputStream和FileOutputStream同理,差异更明显一些。
结论:
  一般情况下,我们应该优先选取BufferedInputStream&BufferedOutputStream。


猜你喜欢

转载自blog.csdn.net/u012273935/article/details/80205984