BufferedInputStream如何缓冲IO以及InputStream中的read(byte[] b) 是否具有缓冲功能?

java中BufferedInputStream缓存为什么使IO效率高? 背景     最近在看socket编程,这里面需要用到stream进行数据的读取和写入。于是代码中用到了BufferedInputStream提高读的效率。所以就一直在想为什么加上buffer就能提高效率了,加上之前面试的时候曾有面试官问到过这个问题,当时没有回答上来,并且就上网搜索了一下,发现有个文章是为什么缓存能提高io效率,这个文章中说是因为缓存可以让DMA来处理io流,后面我一直都是这么认为的,今天在网上搜索发现即使你用的是inputstream来读也会用到D 阅读详情

今天做IO练习的时候,突然意识到InputStream本身提供了3个read方法。其中有2个是将字节码读到一个byte数组中,那这个方法不是和BuffereInputStream一样提供了缓冲功能了么?

    翻了翻api,看了看源码,google了半天,只有这兄弟说得靠谱,转载了过来。原文地址:点击打开链接

从顶级的InputStream开始 

InputStream 定义了3个read方法。 

Java代码   收藏代码
  1. read();  
  2. read(byte[]);  
  3. read(byte[],int off,int len);  

第二个read(byte[])其实就是read(b, 0, b.length) ,所以等同于第三个; 

第一个read()方法,api介绍如下: 
引用
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。 
子类必须提供此方法的一个实现。


第三个read()方法,api介绍如下: 
引用
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。 
在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。 

如果 len 为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。 

将读取的第一个字节存储在元素 b[off] 中,下一个存储在 b[off+1] 中,依次类推。读取的字节数最多等于 len。设 k 为实际读取的字节数;这些字节将存储在 b[off] 到 b[off+k-1] 的元素中,不影响 b[off+k] 到 b[off+len-1] 的元素。 

在任何情况下,b[0] 到 b[off] 的元素以及 b[off+len] 到 b[b.length-1] 的元素都不会受到影响。 

类 InputStream 的 read(b, off, len) 方法重复调用方法 read()。如果第一次这样的调用导致 IOException,则从对 read(b, off, len) 方法的调用中返回该异常。如果对 read() 的任何后续调用导致 IOException,则捕获该异常并将其视为到达文件末尾;到达该点时读取的字节存储在 b 中,并返回发生异常之前读取的字节数。在已读取输入数据 len 的请求数量、检测到文件结束标记、抛出异常前,此方法的默认实现将一直阻塞。 建议子类提供此方法更为有效的实现。


关于三段红字的注解: 
第一段:InputStream是所有输入流的顶级类,当然只定义,不实现,具体的由子类去实现,如AudioInputStream, ByteArrayInputStream, FileInputStream等。 
第二段:指明了InputStream的read(byte[],int off,int len)的实现方式,就是简单的调用read()方法而已,而read()方法是一次只读取一个字节,依然每次都要调用底层系统,所以InputStream的read(byte[],int off,int len)性能和直接调用read()一样,byte[]缓冲区在这是摆设。 
第三段:正是由于第二段所说,才建议子类提供性能更好的方式来覆盖read(byte[],int off,int len)方法。 

那InputStream的子类有哪些呢?看下API就知道了,这几只拿FileInputStream来说. 
下面是FileInputStream的部分源码: 
Java代码   收藏代码
  1. public native int read() throws IOException;  
  2.   
  3. private native int readBytes(byte b[], int off, int len) throws IOException;  
  4.   
  5. public int read(byte b[]) throws IOException {  
  6. return readBytes(b, 0, b.length);  
  7.    }  
  8.   
  9. public int read(byte b[], int off, int len) throws IOException {  
  10. return readBytes(b, off, len);  
  11.    }  

这里两个read()方法都是用本地方法实现,因为FileInputStream是跟底层的操作系统交互的,没有比用本地方法来实现的性能更好,更容易的了。所以这里就采用了第三段里的建议,真正实现了缓存的功能,虽然我们并不知道如何实现的。 

那么既然FileInputStream已经实现了缓存来提高性能,那么BufferedInputStream又拿来干嘛? 
先看api介绍: 
引用
BufferedInputStream 为另一个输入流添加一些功能,即 缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。


其实上面所说的“缓冲输入”并不是真正的像FileInputStream那样用本地方法来提高性能,而是指在这基础上,为了程序员操作方便,内部提供了一个缓冲区(byte[1024*8] buf),并装饰了FileInputStream类(构造BufferedInputStram时必须提供被装饰的InputStream就可看出)。 
当用FileInputStream的时候,read()是从底层读一个字节,read(byte[],int off,int len)则是一次性读取了len-off个字节,我们需提供一个byte[]来存放, 
而用BufferedInputStream的时候,其read()其实和read(byte[],int off,int len)一样,内部都是调用构造输入的FileInputStream的read(byte[],int off,int len)方法,将底层数据读入到byte[]里,而且byte[]不需要我们来提供,类本身定义了一个byte[] buf数组来存放这些数据,所以,如果使用BufferedInputStream我们的程序又不需要对byte[]数组操作的话,直接这样写就行了: 
Java代码   收藏代码
  1. FileInputStream fis=new FileInputStream("d:\\a.txt");  
  2. BufferedInputStream bis=new BufferedInputStream(fis);  
  3. int data=0;  
  4. while((data=bis.read())!=-1){  
  5.     //......          
  6. }  

这样虽然也是一次读一个字节,但不是每次都从底层读取数据,而是一次调用底层系统读取了最多buf.length个字节到buf数组中,然后从 buf中 一次读一个字节,减少了频繁调用底层接口的开销。 
等同于  
Java代码   收藏代码
  1. FileInputStream fis=new FileInputStream("d:\\a.txt");  
  2. byte[] mybuff=new byte[1024];  
  3. int count=0;  
  4. while((count=fis.read(mybuff))!=-1){  
  5.      //......  
  6. }  


如果是用BufferedInputStream的read(byte[],int off,int len)那缓冲区则由传入的byte[]来充当(虽然内部其实有时候还用到了buf,但表现出来的就是用传入的byte[]来缓冲)。 

讲了这么多,那如果要缓冲那该用FileInputStream还是BufferedInputStream呢?回到上面紫色的文字,BufferedInputStream主要不是提供buf,而是封装了缓冲和标记/回读的功能。如果你既不用到标记/回读功能,又不要操作中间的缓冲数组,那显而易见直接用FileInputStream的read(byte[],int off,int len)是效率最高的。 

最后说下为什么用缓冲性能就更好,因为应用程序可以将多个字节写入底层输出流中(native read(byte)),而不必针对每个字节写入都调用底层系统(native read())。OutputStream原理基本差不多,这里就不说了。


原文中只用了FileInputStream举例,自己又翻了翻网络中常用的HttpInputStream,发现这个类只是和父类一样read(byte[] b)调用了read()方法,并没用改写为native方法,那是不是意味着这样的情况下,BufferedInputStream包裹在外面一样是一次次的调用底层的read()方法填充到内置的buff数组中中?那这样的缓冲实在是意义有限……

用Python玩转LQR控制:3行核心代码实现倒立摆稳定控制(附Jupyter Notebook) 本文通过Python实战演示了如何使用LQR算法实现倒立摆的稳定控制。文章以直观方式解释LQR原理,提供从系统建模、核心代码求解到参数调优的完整流程,并附有可运行的Jupyter Notebook代码。重点介绍了如何利用SciPy库快速计算最优反馈增益,并通过仿真验证控制效果,为运动控制实践提供了即学即用的指南。 阅读详情

相关推荐

别再手动发通知了!用Python+飞书机器人,5分钟搞定自动化消息推送(附完整代码)

本文详细介绍了如何利用Python和飞书机器人实现自动化消息推送,大幅提升工作效率。通过Webhook调用和Python脚本,可以轻松发送告警、日报等各类消息,并与业务系统深度集成。文章还提供了完整代码示例和避坑指南,帮助开发者快速上手。

weixin_28736335的博客 305

BufferedInputStream的read方法原理

原文地址:http://www.software8.co/wzjs/java/1770.html BufferedInputStream是一个带有缓冲区的输入流,通常使用它可以提高我们的读取效率,现在我们看下BufferedInputStream的实现原理:  BufferedInputStream内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读

yinbucheng的博客 1万+

Ubuntu本地部署CodeX编程助手:CLI配置全指南

本地AI编程助手是当前开发者关注的核心技术趋势,指在不依赖云端API、保障代码隐私前提下,于本地环境运行具备代码理解、多语言补全与知识库检索能力的智能辅助工具。其技术原理涉及模型加载、API网关编排、向量数据库集成及系统级资源调度,关键价值在于可控性、低延迟与合规性。典型应用场景包括企业内网DevOps提效、边缘设备嵌入式开发支持,以及敏感代码场景下的离线编程增强。本文聚焦Ubuntu系统下基于CLI的手动配置路径,深入解析Ollama服务注册、Node.js版本锁定、API Key环境隔离及Qwen2.5

weixin_26804345的博客 593

Java BufferedInputStream read()方法与示例

BufferedInputStream类read()方法 (BufferedInputStream Class read() method) Syntax: 句法: public int read(); public int read(byte[] b_arr, int offset, int length); read() method is available in...

cumtb2009的博客 3522

从RJPG到温度地图:基于大疆TSDK的热红外数据精准处理与Pix4D拼接实战

本文详细解析了如何利用大疆TSDK将无人机拍摄的热红外RJPG图像精准转换为带有地理坐标的温度TIFF文件,并完成Pix4D拼接生成正射温度地图的全流程。文章重点阐述了辐射定标的原理、TSDK关键参数(测量距离、湿度、发射率、反射温度)的设置与微调方法,以及Pix4D处理中的常见报错解决方案,旨在帮助用户实现从原始数据到可分析温度地图的精准处理。

docker7nomad的博客 464

GNSS数据处理新手避坑:手把手教你用GAMP_GOOD下载IGS/MGEX数据(附.cfg文件详解)

本文详细介绍了如何使用GAMP_GOOD进行GNSS数据处理,从基础配置到高级参数调优,帮助新手避开常见错误。内容包括软件安装、配置文件详解、数据源选择、测站文件配置以及性能优化技巧,特别适合GNSS数据处理初学者快速上手。

weixin_30338481的博客 390

Java中BufferedInputStream的read​()方法和read​(byte[] b)方法读取读取文本文件

BufferedInputStream流的内部缓冲区是字节数组 java.io.BufferedInputStream extends InputStream BufferedInputStream:字节缓冲输入流 继承自父类的成员方法: abstract int read​() 从输入流读取数据的下一个字节。 int read​(byte[]b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b 。 void close.

崔凯洋的博客 7214

QGIS实战:5分钟搞定谷歌地图、高德、天地图等多源地图加载(附最新图源URL)

本文详细介绍了如何在QGIS中快速加载谷歌地图、高德、天地图等多源地图,提供2023年验证可用的最新图源URL和配置步骤。从环境准备到高级技巧,涵盖国内外主流地图服务的完整解决方案,帮助用户提升GIS工作效率。

weixin_29210759的博客 1203

关于BufferedInputStream的read(byte b[], int off, int len)方法读取文件部分出现的问题

使用BufferedInputStream的read方法需要注意的一些问题

一个沉迷Java,无法自拔的Coder 1114

AI应用架构师视角:AI技术引发的全球经济格局重构,你看懂了吗?

本文将从AI应用架构师的独特视角,拆解AI技术栈(算力/算法/数据)如何通过"架构渗透"重塑产业价值链,分析中美欧等主要经济体的AI战略差异如何改写全球分工格局,并为企业与个人提供一套可落地的"AI经济适应性框架"。当OpenAI的GPT-4在代码生成、多模态理解上展现出超越人类的能力,当英伟达的H100芯片成为全球科技巨头争抢的"数字石油",当中国的AI大模型在电商、金融等场景实现规模化落地——我们正站在一场由AI技术引发的全球经济重构的临界点上。AI重构全球经济格局的过程,既是挑战,更是机遇。

小白菜的博客 1258

YOLOv8【第一章:基础入门篇·第2节】一文搞定,数据集制作与标注完全指南!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏,该专栏专注于分享我在YOLOv8目标检测模型中的实战经验,涵盖从入门基础到深度优化的全方位解决方案。无论你是计算机视觉的新手,还是具有多年深度学习经验的专家,本专栏都将为你提供高效、可复现的技术方案,助你掌握YOLOv8的核心技术,提升目标检测性能,突破瓶颈,优化模型,并加速项目开发🚀!

**My Coding Family** 1505

BufferedInputStream的read()方法源码解析

BufferedInputSream默认是现实给出了一个8192byte大小的数组。 private static int DEFAULT_BUFFER_SIZE = 8192; public BufferedInputStream(InputStream in) { this(in, DEFAULT_BUFFER_SIZE); } public BufferedInputStre...

不说话装高手 3919

自定义Usecase/Pipeline

Summary of Custom Usecase and Pipeline Configuration in SA8650 QCX Framework This article elaborates on the complete process of customizing a new Usecase and Pipeline based on the SA8650 QCX framework to meet OEM and Tier1 customization requirements, with

qq_39257814的博客 929

BufferedInputStream如何缓冲IO以及InputStream中的read(byte[] b) 是否具有缓冲功能

InputStream本身提供了3个read方法,其中2个是将字节码读到一个byte数组中。这2个方法是不是和BuffereInputStream一样,提供了缓冲功能? 带着这个疑问,分析了下源码。 首先,从顶级的InputStream开始: read(); read(byte[]); read(byte[],int off,int len); 第2个read(byte[])其实就是read(b, 0, b.length) ,所以等同于第3个。 第1个read()方法,api介绍如下:

WorldMvp的专栏 1573

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

BufferedInputStream缓冲IO以及InputStream中的read(byte[] b)

InputStream InputStream是所有输入流的顶级类,当然只定义,不实现,具体的由子类去实现,如AudioInputStream, ByteArrayInputStream, FileInputStream等。 指明了InputStream的read(byte[],int off,int len)的实现方式,就是简单的调用read()方法而已,而read()方法是一次只读取一个字节,...

weixin_45830683的博客 1125

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

BufferedInputStream_字节缓冲输入流

1.BufferedInputStream——字节缓冲输入流 java.io.BufferedInputStream extends InputStream 1.1 继承自父类的成员方法: int read()从输入流中读取数据的第一个字节。 int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。 void close() 关闭此输入流并释放与该流关联的所有系统资源。 1.2 构造方法 BufferedInputStream(InputStream

weiyoo55的博客 783

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

37字符流-字节缓冲输入流:BufferedInputStream

知识点: java.io.BufferedInputStream extends InputStream 字节缓冲输入流: 继承父类的方法: public void close() 关闭此输入流并释放与此流相关联的任何系统资源 public abstract int read()从输入流读取数据的下一个字节 public int read(byte[] b)从输入流中读取一些字节,并将他们存储到字节数组b中 构造方法: BufferedInputStream(InputStream in) 创建...

dengfengling999的博客 2897

字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流

字节流 抽象类InputStream和OutputStream是字节流的顶级父类 所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStream InputStream的常用方法: int read() int read(byte b[]) int read(byte b[], int off, int len) void close() OutputStream的常用方法: v

m0_53821599的博客 4710

Java IO: InputStream

InputStream类是JavaIOAPI中所有输入流的基类。InputStream子类包括FileInputStream,BufferedInputStream,PushbackInputStream等等。参考JavaIO概述这一小节底部的表格,可以浏览完整的InputStream子类的列表。 JavaInputStream例子 InputStream用于读取基于字节的数据,一次读取一个字节,这是一个InputStream的例子: InputStream&nbsp...

weixin_51393513的博客 332

Java IO流(超详细!!!)

本文介绍了Java IO流的基本概念和操作,重点讲解了文件创建、目录操作以及字节流的使用。首先,通过File类可以创建文件对象,并使用createNewFile()方法创建新文件。常用的文件操作方法包括获取文件名、绝对路径、父目录等。目录操作可以通过mkdir和mkdirs创建单级或多级目录,delete用于删除文件或空目录。接着,文章详细介绍了IO流的原理,分为输入流和输出流,以及字节流和字符流。字节流的核心类是InputStream和OutputStream,分别用于读取和写入字节数据。通过示例代码展示

m0_73494933的博客 2933

输入流InputStream的read(byte b[], int off, int len)方法的使用

输入流InputStream的read(byte b[], int off, int len)方法的使用 参数 byte b[] : the buffer into which the data is read. 读取数据的缓冲区 int off : the start offset in array byte b[] . byte b[]中的起始偏移量 int len: the...

过河的小卒子的博客 4211

JDK8源码硬核解析:InputStream、FilterInputStream与BufferedInputStream实现原理

Java IO 是后端开发与面试中的常驻考点,而 InputStream 作为所有字节输入流的抽象基类,其源码设计隐藏着模板方法、装饰器模式与缓冲区调优的底层逻辑。理解 read() 为何返回 int 而非 byte、FilterInputStream 如何作为透传层支撑 BufferedInputStream 等装饰器的自由组合,是掌握高性能文件读取的关键。在 JDK8 环境下,FileInputStream 单字节读取因 JNI 调用频繁而性能低下,BufferedInputStream 通过 8192

weixin_30399155的博客 431

文件到Java中的byte []

如何将java.io.File转换为byte[] ?

asdfgh0077的博客 497

JAVA IO——常用的类

JAVA IO——常用的类

weixin_59796310的博客 696

Java入门到精通-24 IO流——字节流与字符流

本文介绍了Java IO流的核心概念,包括字节流与字符流的使用。主要内容包括: IO流概述:分类、体系结构及输入/输出流的基本概念 File类操作:文件/目录的创建、删除、遍历及递归遍历实现 字节流使用:重点讲解InputStream/OutputStream及其实现类的读写操作 字符流使用:介绍Reader/Writer及其实现类的文本处理方式 文章通过代码示例演示了文件操作、目录遍历以及不同IO流的使用场景,适合作为Java中高级特性的学习参考资料。

weixin_56693899的博客 268

Java 初识IO流笔记

Java 初识IO流笔记 内容:1.常见的输入流FileInputStream的三种read方法使用 2.过程中遇到的编码和类型转换问题分析 1.输入流 InputStream的read方法是抽象方法所以InputStream是抽象类,不能直接使用可以: InputStream fis=new FileInputStream("url"); read() hello.txt中的内容: hello FileInputStream实现read()方法时返回的是一个int值,如果为-1则说明流已经读完了,

qq_53600812的博客 334
上一篇: Hibernate知识要点复习(2) 一对一双向关联(注解)及 关联中各种注释的作用
下一篇: spring-kafka消费消息后的提交方式
大飞Tobi
博客等级 码龄16年 54粉丝 14原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值