Java IO | InputStream与OutputStream 简介(六)

InputStream 和 OutputStream 对于字节流的输入和输出, 是做为协议的存在。 因此有必要了解下这两个类提供出来的基本约定。 这两个类是抽象类,并且基本上没什么实现,都是依赖于子类具体的去实现, 可是他是对于其子类协议纲领通常的存在。 了解清楚每个方法含义,对于后续具体的子类将会有很是大的帮助。  1 

基本含义

InputStream 全部字节输入流的超类
是一个抽象类
OutputStream 全部字节输出流的超类
他是一个抽象类

 2 

方法列表

图片
  • InputStream  包含了读取方法以及辅助方法;数组

  • OutputStream包含了写入方法以及辅助方法;app


 3 ide

方法对照


 4 测试

方法详解

 read read()  从输入流中读取数据的下一个字节。 返回 0 到 255 范围内的 int 字节值,若是由于已经到达流末尾而没有可用的字节,返回值 -1。 方法将会一直阻塞,直到数据可用,检测到流的末尾或者抛出异常
无参数的read() 是抽象方法,由实现类提供实现, 三个read方法实际上根本方法都是read()方法, 其余两个方法为拓展功能逻辑的便捷方法。
无参数的read()返回的数据为读取到的字节值, 而有参数的则是读取到字节数组中,因此返回值为读取到的个数
read方法关键点:
要么就是直接返回读取的字节;
要么就是将读取到的字节放入字节数组中,字节数组是你传递进去的;
write write(int b) 将指定的字节写入此输出流
write 的常规协定是:向输出流写入一个字节, 要写入的字节是参数 b 的八个低位   b 的 24 个高位将被忽略 
说白了就是写入的是byte虽然参数是int

write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流 write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果彻底相同
write(byte[] b,int off,int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流 write(b, off, len) 的常规协定是:将数组 b 中的某些字节按顺序写入输出流; 元素 b[off] 是此操做写入的第一个字节,b[off+len-1] 是此操做写入的最后一个字节
相似read的调用形式, 直接写入指定字节的write(int b)  方法是根本, 其余的是拓展功能
read()  与write(int b) 是根本的读取一个字节或者写入一个字节的方法。
其他形式是针对传入字节数组做为参数,以及指定字节数组的偏移量时的一些拓展功能。
一旦传递了字节数组做为参数,read将会读取数据到字节数组,write将会将字节数组的数据写入。

close 都须要关闭流,因此都有close方法;
都是关闭流并释放与此流有关的系统资源;
均可能抛出IOException;
在InputStream和OutputStream中,两个close方法都是空方法;
flush flush的含义为刷新,在写入数据时使用。
因此只有输出流拥有flush方法
之因此须要刷新,是由于有的输出流的写方法实现,可能已经缓冲了之前写入的任何字节,那么,这个方法用于提供可以当即将数据写入到磁盘的功能。
不过只是当即请求操做系统进行处理,而不保证这些字节实际已经写入到物理设备,好比磁

下面几个为InputStream独有
public int available()  throws IOException
返回此输入流下一个方法调用能够不受阻塞地今后输入流读取(或跳过)的估计字节数。
这句话有些绕口,直白的说就是: 在方法调用前,能够获取到这个流中可用的字节数目。 假设说有N个字节可使用,显然你应该极可能读取到N个字节,,或者可以跳过N个字节, 一次读取或跳过此估计数个字节不会受阻塞。
注意:
这个数目是一个预估的数量,实际的读取或者跳过的字节数可能小于这个数。


InputStream中的这个方法老是返回0  ,因此这个方法可否使用依赖于子类的实现。
public long skip(long n) throws IOException
返回的是实际跳过的字节数。
在内部建立一个 byte 数组,而后重复将字节读入其中,直到读够 n 个字节或已到达流末尾为止。
reset()mark(int)markSupported()
三个方法是对于同一个功能点的不一样方法  ,能够解决重复读的问题
mark(int)用来在此输入流中作标记,标记当前位置  打一个书签;
markSupported()   测试此输入流是否支持 mark 和 reset 方法;
reset()  将此流从新定位到最后一次对此输入流调用 mark 方法时的位置   回到书签
看下类中的默认代码能够发现:
  • 默认状况下mark什么都不作;spa

  • markSupported直接返回false;操作系统

  • reset方法的调用会抛出异常;code


图片
mark的参数用于告知输入流在标记位置失效以前容许读取的字节数 标记已关闭的流对其无效
提及来很迷惑,用起来却很简单
好比 
//代表系统至少应该缓冲50以上个数据,以保证能够回来从新读取xxxStream.mark(50);xxxStream.read();.....xxxStream.read();
//reset以后,读取到的数据将会和刚才调用mark 方法后read的数据是相同的xxxStream.reset();xxxStream.read();.....xxxStream.read();
若是方法 markSupported 返回 true,那么输入流老是在调用 mark 以后记录全部读取的字节,并时刻准备在调用方法 reset 时(不管什么时候),再次提供这些相同的字节。
可是,若是在调用 reset 以前能够从流中读取多于 readlimit 的字节,则不须要该流记录任何数据。

https://mp.weixin.qq.com/s/c8MFam2AdJydyKeUHPqaqgorm

相关文章
相关标签/搜索