前言

适合人群:不用啥特别基础的小白

本文的写作目的在于我发现身边很多人对于缓冲流可能有误区,知道得不够全面,一般会有如下几个观点:

1.缓冲流是用于包装其他流,达到缓冲加速的目的,性能要比普通流要好

2.缓冲流利用了缓冲区,字节一次过读取到缓冲区中,只进行了一次磁盘IO,然后再从缓冲区读取数据,而普通流每读一个字节都需要进行一次磁盘IO,缓冲流大大降低了磁盘IO次数而达到了性能提高的效果。

原理

实际上,以上两个观点都不太对,也不能说全错,大概都对了一半,先回答一下真实情况:

1.缓冲流在大部分情况是要比普通流性能高,这个大部分情况可以粗略认为就是在于读取数据用的数组长度<8196的时候,而在数组长度>8196的情况下很可能性能反而更加低

2.普通流读取数据确实要每个字节都要磁盘IO,但是缓冲流同样也要每个字节磁盘IO先读进缓冲区,然后再从缓冲区里读,并非说用了缓冲流就只需要一次磁盘IO

缓冲流的具体实现其实是这样的:

流程总结如下:

(假设现在有缓冲流bufferedStream,它所包装的普通流为normalStream)

1.缓冲区里初始化一个长度为8196的数组当做缓冲区buf

2.读取数据时先调用normalStream.read(buf),用普通流把数据读进buf,这个步骤说明了缓冲流依然逃不开每读一个字节就需要进行一次IO

3.调用System.arraycopy()方法把数据从缓冲区buf复制到加载数据的数组中

4.另外:如果读取数据的数组长度>8196,那么将会不使用缓冲区,进行直接读取

具体源码就没必要写出来了,在哪里可以看到呢,可以给大家指明一下:

(现在拿BufferedInputStream为例,大家可以自行对比自己去看BufferedOutputStream,我是JDK1.8)

1.流程第一段在183和203行的这一句buf = new byte[size]

2.流程第二段在265和246行的fill()以及里面的getInIfOpen().read(buffer, pos, buffer.length - pos)

3.流程第三段在291行的read1()方法里面的System.arraycopy(getBufIfOpen(), pos, b, off, cnt)

4.流程第四段在282行的read1()方法里面的getInIfOpen().read(b, off, len)

证明

其实上面从理论上已经证明了,现在从实际效果看一看,直接上代码:

public class BufferedStreamTest {public static void main(String[] args){File file = new File("C:\\Users\\Administrator\\Desktop\\test.txt");try {byte[] buf1 = new byte[128];byte[] buf2 = new byte[8196];byte[] buf3 = new byte[8196 * 1024];readData(file,buf1,false);readData(file,buf1,true);readData(file,buf2,false);readData(file,buf2,true);readData(file,buf3,false);readData(file,buf3,true);}catch (Exception e){e.printStackTrace();}}public static void readData(File file,byte[] buf,boolean isBuffered)throws Exception{FileInputStream fis = new FileInputStream(file);BufferedInputStream bfis = new BufferedInputStream(fis);InputStream inputStream = isBuffered?bfis:fis;long startTime = System.currentTimeMillis();while (inputStream.read(buf)!= -1){}System.out.println(inputStream+"--buf_length_"+buf.length+" 耗时为: "+(System.currentTimeMillis() - startTime));System.out.println("----------------------------------------------------");}
}

注意点:

1.这里读取的文件test.txt的大小在26MB,由于现在的计算机性能都很好,文件太小效果不明显

2.自己做实验的时候,inputStream不要复用,一定要每一次都要新new的,不要前面已经读取完了,用同一个inputStream相当于没数据可读,耗时会是0

3.为了消除计算机硬件层面的缓存的影响,我都是把普通流写在缓冲流前面,以消除缓冲流读完后因为有了缓存所以普通流才读得快的情况

我们来看看结果:

从结果就能看出来了:

1.当数组长度小于8196,缓冲流明显更快

2.当数组长度等于8196,缓冲流和普通流速度 相当(实际上缓冲流因为附加逻辑判断的原因还会更慢,图上结果缓冲流快2s只是因为计算机底层硬件缓存导致的)

3.当数组长度大于8196,普通流是要快于缓冲流的,因为缓冲流多了许多附加逻辑的原因会有性能损耗,不过倒是很轻微的损耗

结论

1.缓冲流不一定比普通流快,但是慢的时候也慢不了多少

2.缓冲流也要进行多次磁盘IO,这取决于缓冲流所包装的普通流的read()方法的实现了,因为本质就是调用了所包装的普通流的read(buf)

在实际开发建议多使用缓冲流没什么问题,它为程序员屏蔽了很多细节,让大家不用考虑太多就有一种“缓冲流可以加速”的体验感;当然了,如果经验比较丰富的话,而且对内存空间以及极限速度有更大追求的话,缓冲流就不一定是个好选择,可以根据需要去实现自己IO模型。

Java缓冲流BufferedStream详解相关推荐

  1. Java IO流使用详解

    1.前言 在众多流行的编程语言中,Java对IO的处理应该是最特殊的,Java打着"尽量减少IO类的设计理念",搞出了目前应该是最复杂的一套IO相关类,并称之为Java流. 对于新 ...

  2. Java Stream流(详解)

    一.Stream流引入 Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,用于解决集合类库既有的鼻端.(Lambda表达式详解在上篇博客内容)         ...

  3. Java IO流(详解)

    1. File 1. 创建 2. 操作 1. 获取文件信息 2. 目录创建/删除 2. IO流 1. FileInputStream 1. 简单使用 2. 读取中文 2. FileOutputStre ...

  4. Java 8流处理详解

    一.初识流 1. 什么是流? 流是Java API的新成员,它允许你以声明性方式(类似SQL,只写做什么,不考虑怎么做)处理数据集合.流就是从支持数据处理操作的源生成的元素序列.源可以是集合.数组或I ...

  5. Java快速输入输出使用详解(解决Java输入输出超时问题)

    Java快速输入输出使用详解 一.背景:   Scanner类输入时,虽然方式很简单,但是输入实在太慢了,经常遇到大的数据量时候就超时.(你觉得数据有点多时就用快速输入即可)   某些题目用Scann ...

  6. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java 8引入 ...

  7. java定时任务框架elasticjob详解

    这篇文章主要介绍了java定时任务框架elasticjob详解,Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架.该项目基于成熟的开源产品Quartz和Zo ...

  8. Java 内存模型 JMM 详解

    转载自 Java 内存模型 JMM 详解 JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性.是否可以重排序等问题的无关具体 ...

  9. java 8 新功能详解_Java 8和Java 14之间的新功能

    java 8 新功能详解 从版本9开始,Java每6个月就有一次新功能,因此很难跟踪这些新更改. 互联网上的大多数信息都描述了最近2个Java版本之间的变化. 但是,如果您的情况与我相似,则说明您使用 ...

最新文章

  1. 【软件需求工程与建模 - 小组项目】阶段性汇报-软件设计规格说明书3.0
  2. 死磕算法!精选35篇算法设计实例+6本必读书打包送你
  3. 「PDF Expert」macOS 全能型 PDF 工具——功能介绍
  4. python猜积木_Python中乐高积木——函数
  5. mongoTemplate.aggregate() 聚合查询,关联查询
  6. Linux用php上传表单文件,文件太大提示[413 Request Entity Too Large]
  7. ITIL配置管理流程设计
  8. 无猿无故!程序员成语大全
  9. thinkphp 检测上传的图片中是否含有木马脚本
  10. npm install 很慢、卡死怎么解决
  11. 大学本科计算机考试小抄,大学考试允许带小抄 一页开卷学生抄到手酸
  12. 照片、摄影处理中的基本知识
  13. IP地址、子网掩码、默认网关和DNS服务器之间的联系与区别
  14. 驱动开发 环境搭建(Win7-VS2008+WDK+DDKWzard)
  15. Android应用在国外之各种广告集成(Vungle,AppLovin,Google,Facebook)
  16. 自由天空综合驱动包集合
  17. plotclock绘图钟也可以画小猪佩奇
  18. jquery file upload 限制上传文件的格式、大小或图片尺寸
  19. 魅色android安装包,Android 安装包
  20. 硬件(R820T+RTL2832)+RTL1090+adsbscope接收ADS-B信号

热门文章

  1. vue项目,内网预览.xls .pptx .ppt .doc .docx .xlsx等格式的文件方法推荐
  2. 用web用户控件的方式添加到webpart,使用ajax实现无刷新总结
  3. 欢聚时代c++开发岗位面试经验
  4. Rimini Street公布2019年第三财季财务业绩
  5. chrome android 2.3,【安卓2.3谷歌框架单刷包】安卓2.3谷歌GMS服务框架
  6. VS对战平台发布1.1.7内部测试版
  7. js在html中拆分字符串,js中的split方法 js用split()取字符串
  8. CM5800内置 100V/5A MOS 宽输入电压降压型 DC-DC
  9. activity简单跳转
  10. 网站服务器回档,如何解决网站快照回档?