Jdk8源码阅读之InputStream

InputStream

InputStream抽象类是所有字节输入流的类的超类

InputStream实现了一个Closeable接口。
这里写图片描述

在接口Closeable中只定义了一个close()方法。
这里写图片描述

具有以下属性和方法:

(1)MAX_SKIP_BUFFER_SIZE:定义了跳过时最大缓冲大小,这里设置了一个默认值是2048。

这里写图片描述

(2)read():从输入流中读取数据的下一个字节,返回的字节的值是一个int类型,范围在0到255之间。如果没有有效的字节,因为已经到达流的终点,返回-1。当输入数据有效时,方法块会一直运行,直到检测已到达流的终点,或是抛出了异常。read是一个抽象方法,子类需要提供这个方法的实现。

这里写图片描述

(3)read(byte b[], int off, int len):从输入流中读取数据的len个字节到字节数组b,存放位置从b的off位置开始。

这里写图片描述

从上面这张图片可以看到,这个read(byte b[], int off, int len)方法就是重复调用len次read()方法。在第一次调用read()方法时,如果read()抛出了IOException异常,这里会直接抛出。而在接下来的len-1次中调用read()方法,如果read()方法抛出异常,这里是利用了try{}catch(){}进行捕获,最后会返回异常发生前进行到的指针i,也就是读取到的字节总数。

这个方法会一直运行直到读取了len个字节,或是检测运行到文件的结尾,或是抛出了异常。

(4)read(byte b[]):这个方法的底层实现是调用了read(byte b[],int off,int len)方法。这个方法是默认从输入流中读取数组b的长度个字节。

这里写图片描述

(5)skip(long n):跳过或是丢弃输入流的n个字节的数据。会因为很多原因,最终跳过的字节数小于希望跳过的字节数n,也许是0。其中一个可能的原因就是到达了文件的尾部。

这里写图片描述

比较传入的要跳过的字节数和设置的默认的跳过时的缓存值,选择小的那一个定义为size。定义一个大小为size的字节数组,调用read(byte b[], int off, int len)方法,读取字节数据到字节数组中。read(byte b[], int off, int len)每次返回读取到的字节总数,remaining存储还没有跳过的字节数,最后返回跳过的字节数。

(6)available():在父类,这个方法的返回值总是0,这是一个需要被子类覆盖的类。这个方法是用来返回可以从输入流中读取(或是跳过)的字节数的估计值,而不需要对该输入流进行下一次的调用。下一次的调用也许是同一个线程或是另外一个线程。许多字节的单个读取或是跳过不会阻塞,但是可能会读取或是跳过更少的字节。

这里写图片描述

注意:一些InputStream的实现类会返回流的总字节数,更多的不会。使用这个方法的返回值来分配一个缓冲,以此来保存流中全部的数据,是不正确的。

如果输入流已经通过调用close()方法被关闭了,这个方法子类的实现可能会选择抛出一个IOException。

(7)close():关闭当前输入流以及释放和这个流有关的系统资源。在InputStream中这是一个空方法。

这里写图片描述

(8)markSupported():测试这个输入流是否支持mark和reset方法。mark()和reset()方法是否是一个特定的输入流的不变的属性。InputStream抽象类的markSupported()方法返回false。

这里写图片描述

(9)reset():将此流重新定位到mark()方法上次调用该流的位置。在InputStream抽象类中,做的仅仅是抛出一个IOException。

这里写图片描述

有以下两种情况:
第一种情况:markSupported()方法返回true:

如果自从流生成,mark()方法都没有被调用,或者上次调用mark()方法从流中读取的字节的数量比上次调用mark()方法传入的参数大,可能会抛出IOException。

如果没有抛出IOException,该流会被重置成一种状态,从最近mark()方法的调用,所有字节的读取(或者如果mark()方法没有被调用过,从开始以来的文件)会补充后续调用者的读方法,其次是所有字节,否则下一次输入数据的时候会调用reset()方法。

第二种情况:markSupported()方法返回false:

调用reset()方法会抛出IOException异常。

如果IOException没有被抛出,流会被重置为一种固定的状态,取决于输入流的特定类型和输入流是如何生成的。字节会被提供后续调用者的读方法,取决于输入流的特定类型。

(10)mark():标记在此输入流中的当前位置。reset()方法的后续调用将在最后一个标记位置重新定位此流,以便后续读取相同的字节。

这里写图片描述

参数readlimit告诉输入流允许读取多少字节在标记位置失效之前。

一般的mark契约是:
如果markSupported()方法返回true
流会以某种方式记住在调用mark()方法后读取的全部字节和随时准备好当调用reset()方法时,再次提供相同的字节。然而,流并不被要求记住全部的数据,如果在调用reset()方法前从流中读取了超过readlimits字节的数据。

标记一个关闭的流不应该对流产生任何的影响。

以上是我结合有道翻译对jdk8的InputStream抽象类做的学习笔记,有什么改正的建议,希望读者们提出,谢谢大家阅读到这里。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值