Java IO 之 InputStream源码(2)

Writer:李强强

一、InputStream

InputStream是一个抽象类,即表示所有字节输入流实现类的基类。它的作用就是抽象地表示所有从不同数据源产生输入的类,例如常见的FileInputStream、FilterInputStream等。那些数据源呢?比如:

1) 字节数组(不代表String类,但可以转换)

2) String对象

3) 文件

4) 一个其他种类的流组成的序列化 (在分布式系统中常见)

5) 管道(多线程环境中的数据源)

等等

二者,注意它是属于字节流部分,而不是字符流(java.io中Reader\Writer,下面会讲到)。

FilterInputStream是为各种InputStream实现类提供的“装饰器模式”的基类。因此,可以分为原始的字节流和“装饰”过的功能封装字节流。

二、细解InputStream源码的核心

源码如下:


/*** 所有字节输入流实现类的基类*/
public abstract class SInputStream {// 缓存区字节数组最大值private static final int MAX_SKIP_BUFFER_SIZE = 2048;// 从输入流中读取数据的下一个字节,以int返回public abstract int read() throws IOException;// 从输入流中读取数据的一定数量字节,并存储在缓存数组bpublic int read(byte b[]) throws IOException {return read(b, 0, b.length);}// 从输入流中读取数据最多len个字节,并存储在缓存数组bpublic int read(byte b[], int off, int len) throws IOException {if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();} else if (len == 0) {return 0;}int c = read();if (c == -1) {return -1;}b[off] = (byte)c;int i = 1;try {for (; i < len ; i++) {c = read();if (c == -1) {break;}b[off + i] = (byte)c;}} catch (IOException ee) {}return i;}// 跳过输入流中数据的n个字节public long skip(long n) throws IOException {long remaining = n;int nr;if (n <= 0) {return 0;}int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);byte[] skipBuffer = new byte[size];while (remaining > 0) {nr = read(skipBuffer, 0, (int)Math.min(size, remaining));if (nr < 0) {break;}remaining -= nr;}return n - remaining;}// 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数public int available() throws IOException {return 0;}// 关闭此输入流,并释放与其关联的所有资源public void close() throws IOException {}// 在此输出流中标记当前位置public synchronized void mark(int readlimit) {}// 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。public synchronized void reset() throws IOException {throw new IOException("mark/reset not supported");}// 测试此输入流是否支持 mark 和 reset 方法public boolean markSupported() {return false;}}


其中,InputStream下面三个read方法才是核心方法:


public abstract int read()


抽象方法,没有具体实现。因为子类必须实现此方法的一个实现。这就是输入流的关键方法。

二者,可见下面两个read()方法都调用了这个方法子类的实现来完成功能的。

 


public int read(byte b[])


该方法是表示从输入流中读取数据的一定数量字节,并存储在缓存字节数组b。其效果等同于调用了下面方法的实现:


 read(b, 0, b.length)


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

思考:这时候,怪不得很多时候, b != –1 或者 b != EOF

 


public int read(byte b[], int off, int len)



在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。

该方法先进行校验,然后校验下个字节是否为空。如果校验通过后,
如下代码:


int i = 1;
try {for (; i < len ; i++) {c = read();if (c == -1) {break;}b[off + i] = (byte)c;}
} catch (IOException ee) {
}


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

 

 

 

因为有上面两个read的实现,所以这里InputStream设计为抽象类。

三、小结

1. InputSream 对应着 OutputStream

2. 看源码是享受人家写代码中流露的How

3. 泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CTSC2017】【BZOJ4903】吉夫特 卢卡斯定理 DP

题目描述 给你一个长度为\(n\)的数列\(a\)&#xff0c;求有多少个长度\(\geq 2\)的不上升子序列\(a_{b_1},a_{b_2},\ldots,a_{b_k}\)满足\[ \prod_{i2}^k\binom{a_{b_{i-1}}}{a_{b_i}}\mod 2>0 \]   答案对\({10}^97\)取模。 \(n\leq211985,a_i\leq 233333\) \(\forall i\…

深度学习修炼(七)——卷积神经网络

文章目录7 卷积神经网络7.1 卷积网络和传统网络的区别7.2 卷积7.2.1 卷积过程画大饼7.2.2 图像的不变性7.2.3 互相关运算*(补充)7.2.4 图像颜色通道*(补充)7.2.5 步幅7.2.6 多次卷积7.2.7 边缘填充7.2.8 特征图的大小7.2.9 卷积参数共享7.3 池化7.4 整体网络架构7.5 后话7 卷积…

Java并发编程:ThreadLocal

Java并发编程&#xff1a;深入剖析ThreadLocal ThreadLocal ThreadLocal之我见 Struts2中的设计模式----ThreadLocal模式 ThreadLocal ThreadLocal原理及其实际应用 ThreadLocal 转载于:https://www.cnblogs.com/a198720/articles/4229366.html

用递归形成树结构数据

定义一个树形实体 public class orgTrees{public orgTrees(){this.Children new List<orgTrees>();}public int Id { get; set; }public int FatherId { get; set; }public string Name { get; set; }public int Lever { get; set; }public bool HasChildren { get; se…

网络爬虫(一)——爬虫及其实现

文章目录1.1 爬虫概述1.1.3 网络爬虫和浏览器的区别1.1.2 网络爬虫的定义1.2 requests请求库1.2.1 requests基本概念1.2.2 疫情数据爬取1.2.3 get请求1.2.4 headers请求头1.2.5 Cookies验证1.3 Beautiful Soup解析库1.3.1 安装1.3.2 对象的创建1.3.3 find方法1.3.4 后话1.4 正则…

C# winform 窗体怎么隐藏标题栏,不显示标题栏

//没有标题 this.FormBorderStyle FormBorderStyle.None; //任务栏不显示 this.ShowInTaskbar false;转载于:https://www.cnblogs.com/qq260250932/p/4230472.html

sqL编程篇(三) 游标与存储过程

sql编程2 游标与存储过程 sql编程中的游标的使用&#xff1a;提供的一种对查询的结果集进行逐行处理的一种方式不用游标的处理解决方式&#xff1a;逐行修改工资update salar set 工资‘新工资’ where 雇员号0101 //通过查出雇员号而修改工资过程&#xff1a;1.定义一个游标&a…

python爬虫从入门到精通

第一讲 什么是爬虫 网络蜘蛛&#xff08;Web spider&#xff09;也叫网络爬虫&#xff08;Web crawler&#xff09;&#xff0c;蚂蚁&#xff08;ant&#xff09;&#xff0c;自动检索工具&#xff08;automatic indexer&#xff09;&#xff0c;或者&#xff08;在FOAF软件概念…

Windows五种IO模型性能分析和Linux五种IO模型性能分析

Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blog.csdn.net/jay900323/article/details/18140847 重叠I/O模型的另外几个优点在于&#xff0c;微软针对重叠I/O模型提供了一些特有的扩展函数。当使用重…

C++从0到1的入门级教学(十一)——友元

文章目录11 友元11.1 全局函数做友元11.2 友元类11.3 成员函数做友元11 友元 让我们引入一个例子来讲述友元是什么。 生活中你的家有客厅&#xff0c;有卧室&#xff0c;客厅所有来的客人都可以进去&#xff0c;但是你的卧室是私有的。对于认识的人来说你可以允许它进去&…

KeyMob:为国内应用开发者管理的广告聚合平台

为什么80%的码农都做不了架构师&#xff1f;>>> 应用开发者在应用中嵌入广告SDK的来源主要包括两种&#xff1a;使用移动广告平台与移动广告聚合平台。国内有多少家提供移动广告管理的平台&#xff1f;据统计&#xff0c;这两个版本&#xff0c;已经有四五十家。虽…

模拟航班查询及预定系统 编写示例

一、建立C#窗体 所需控件&#xff1a; Label标签 Button 按钮 TextBox 文本框 ComboBox 组合框 DATaGridView 数据显示 DateTimePicker 日期表 NumericUpDown 数字选择 二、建立后台数据库 大概需要四张表 1&#xff0c;航空公司表 2&#xff0c;城市信息表 3&#xff0c;航班…

package

package转载于:https://www.cnblogs.com/wangweiabcd/p/4232646.html

数据结构杂谈(七)——串

文章目录7 串7.1 基本知识7.1.1 串的定义:rose:定义:rose:各种概念:rose:字符串和线性表的区别7.1.2 串的抽象类型数据定义7.1.3 串的比较:rose:原理7.2 串的存储结构:rose:7.2.1串的顺序存储:rose:7.2.2 串的链式存储7.3 基本操作:rose:7.3.1 返回子串操作:rose:7.3.2 比较操作…

牛刀小试Oracle之ORACLE 11GR2 RAC安装配置--检测GI软件是否正常(三)

1. 切换至grid用户[rootZracnode1 ~]# su - grid2.查看CRS状态(目前Oracle11GR2官方文档&#xff0c;不建议用如下命令检测了&#xff0c;等我有时间在整理补充)[gridZracnode1 ~]$ crs_stat -tName Type Target State Host ---------------…

PHP十六个魔术方法

PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods)&#xff0c;这些方法在PHP中充当了举足轻重的作用。 魔术方法包括&#xff1a; __construct()&#xff0c;类的构造函数__destruct()&#xff0c;类的析构函数__call()&#xff0c;在对象中调用一个不可访问方法时…

Linux实现的IEEE 802.q VLAN

本文转载自&#xff1a; http://blog.chinaunix.net/uid-20786208-id-4291059.html Technorati 标签: Linux VLAN--------------------------我是快乐的分割线-------------------------------------------------- 第一部分&#xff1a;VLAN的核心概念 说起IEEE 802.1q&#xf…

C++从0到1的入门级教学(十二)——运算符重载

文章目录12 运算符重载12.1 加法运算符重载12.2 左移运算符重载12.2.1 演示与说明12.2.2 常见的友元使用&#xff1a;重载>>运算符12.3 递增运算符重载12.4 赋值运算符重载12.5 关系运算符重载12.6 函数调用运算符重载12 运算符重载 在本讲中&#xff0c;我们会设计到一…

IntelliJ IDEA 显示行号方法

为何N多人问这问题&#xff0c;设置方法如下&#xff1a;File->Settings->Editor->General->Appearence->Show Line Number

python项目构建工具zc.buildout

转载&#xff1a;http://blog.csdn.net/u011630575/article/details/52940099 buildout简介 Buildout 是一个基于Python的构建工具, Buildout 主要是为了解决两个问题: 中心化的应用组装和部署重复的从Python软件发布中组装项目通过一个配置文件 buildout.cfg , 可以从多个部分…