Java缓冲流BufferedStream详解
前言
适合人群:不用啥特别基础的小白
本文的写作目的在于我发现身边很多人对于缓冲流可能有误区,知道得不够全面,一般会有如下几个观点:
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详解相关推荐
- Java IO流使用详解
1.前言 在众多流行的编程语言中,Java对IO的处理应该是最特殊的,Java打着"尽量减少IO类的设计理念",搞出了目前应该是最复杂的一套IO相关类,并称之为Java流. 对于新 ...
- Java Stream流(详解)
一.Stream流引入 Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,用于解决集合类库既有的鼻端.(Lambda表达式详解在上篇博客内容) ...
- Java IO流(详解)
1. File 1. 创建 2. 操作 1. 获取文件信息 2. 目录创建/删除 2. IO流 1. FileInputStream 1. 简单使用 2. 读取中文 2. FileOutputStre ...
- Java 8流处理详解
一.初识流 1. 什么是流? 流是Java API的新成员,它允许你以声明性方式(类似SQL,只写做什么,不考虑怎么做)处理数据集合.流就是从支持数据处理操作的源生成的元素序列.源可以是集合.数组或I ...
- Java快速输入输出使用详解(解决Java输入输出超时问题)
Java快速输入输出使用详解 一.背景: Scanner类输入时,虽然方式很简单,但是输入实在太慢了,经常遇到大的数据量时候就超时.(你觉得数据有点多时就用快速输入即可) 某些题目用Scann ...
- Java 8 Stream API详解--转
原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java 8引入 ...
- java定时任务框架elasticjob详解
这篇文章主要介绍了java定时任务框架elasticjob详解,Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架.该项目基于成熟的开源产品Quartz和Zo ...
- Java 内存模型 JMM 详解
转载自 Java 内存模型 JMM 详解 JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性.是否可以重排序等问题的无关具体 ...
- java 8 新功能详解_Java 8和Java 14之间的新功能
java 8 新功能详解 从版本9开始,Java每6个月就有一次新功能,因此很难跟踪这些新更改. 互联网上的大多数信息都描述了最近2个Java版本之间的变化. 但是,如果您的情况与我相似,则说明您使用 ...
最新文章
- 【软件需求工程与建模 - 小组项目】阶段性汇报-软件设计规格说明书3.0
- 死磕算法!精选35篇算法设计实例+6本必读书打包送你
- 「PDF Expert」macOS 全能型 PDF 工具——功能介绍
- python猜积木_Python中乐高积木——函数
- mongoTemplate.aggregate() 聚合查询,关联查询
- Linux用php上传表单文件,文件太大提示[413 Request Entity Too Large]
- ITIL配置管理流程设计
- 无猿无故!程序员成语大全
- thinkphp 检测上传的图片中是否含有木马脚本
- npm install 很慢、卡死怎么解决
- 大学本科计算机考试小抄,大学考试允许带小抄 一页开卷学生抄到手酸
- 照片、摄影处理中的基本知识
- IP地址、子网掩码、默认网关和DNS服务器之间的联系与区别
- 驱动开发 环境搭建(Win7-VS2008+WDK+DDKWzard)
- Android应用在国外之各种广告集成(Vungle,AppLovin,Google,Facebook)
- 自由天空综合驱动包集合
- plotclock绘图钟也可以画小猪佩奇
- jquery file upload 限制上传文件的格式、大小或图片尺寸
- 魅色android安装包,Android 安装包
- 硬件(R820T+RTL2832)+RTL1090+adsbscope接收ADS-B信号
热门文章
- vue项目,内网预览.xls .pptx .ppt .doc .docx .xlsx等格式的文件方法推荐
- 用web用户控件的方式添加到webpart,使用ajax实现无刷新总结
- 欢聚时代c++开发岗位面试经验
- Rimini Street公布2019年第三财季财务业绩
- chrome android 2.3,【安卓2.3谷歌框架单刷包】安卓2.3谷歌GMS服务框架
- VS对战平台发布1.1.7内部测试版
- js在html中拆分字符串,js中的split方法 js用split()取字符串
- CM5800内置 100V/5A MOS 宽输入电压降压型 DC-DC
- activity简单跳转
- 网站服务器回档,如何解决网站快照回档?