[五]JavaIO之InputStreamOutputStream简介方法列表说明
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[五]JavaIO之InputStreamOutputStream简介⽅法列表说明
InputStream 和 OutputStream 对于字节流的输⼊和输出
是作为协议的存在
所以有必要了解下这两个类提供出来的基本约定
这两个类是抽象类,⽽且基本上没什么实现,都是依赖于⼦类具体的去实现
但是他是对于其⼦类协议纲领⼀般的存在
了解清楚每⼀个⽅法含义,对于后续具体的⼦类将会有⾮常⼤的帮助
基本含义
InputStream所有字节输⼊流的超类他是⼀个抽象类
OutputStream所有字节输出流的超类他是⼀个抽象类
⽅法列表
InputStream 包含了读取⽅法以及辅助⽅法
OutputStream包含了写⼊⽅法以及辅助⽅法
⽅法对照
read()
read(byte[])
read(byte[], int, int)write(byte[])
write(byte[], int, int) write(int)
close close
flush() available()
mark(int)
markSupported()
reset()
skip(long)
⽅法详解
read
read() 从输⼊流中读取数据的下⼀个字节。返回 0 到 255 范围内的 int 字节值如果因为已经到达流末尾⽽没有可⽤的字节,则返回值 -1
⽅法将会⼀直阻塞,直到数据可⽤,检测到流的末尾或者抛出异常
⽆参数的read() 是抽象⽅法,由实现类提供实现
三个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 个字节或已到达流末尾为⽌
在内部创建⼀个 byte 数组,然后重复将字节读⼊其中,直到读够 n 个字节或已到达流末尾为⽌reset()
mark(int)
markSupported()
三个⽅法是对于同⼀个功能点的不同⽅法 ,可以解决重复读的问题
mark(int)⽤来在此输⼊流中做标记,标记当前位置打⼀个书签
markSupported() 测试此输⼊流是否⽀持 mark 和 reset ⽅法
reset() 将此流重新定位到最后⼀次对此输⼊流调⽤ mark ⽅法时的位置回到书签
看下类中的默认代码可以发现:
默认情况下mark什么都不做
markSupported直接返回false
reset⽅法的调⽤会抛出异常
mark的参数⽤于告知输⼊流在标记位置失效之前允许读取的字节数
标记已关闭的流对其⽆效
说起来很迷惑,⽤起来却很简单
⽐如
xxxStream.mark(50);//表明系统⾄少应该缓冲50以上个数据,以保证可以回来重新读取xxxStream.read();
.....
xxxStream.read();
xxxStream.reset();//reset之后,读取到的数据将会和刚才调⽤mark ⽅法后read的数据是相同的xxxStream.read();
.....
xxxStream.read();
如果⽅法 markSupported 返回 true,那么输⼊流总是在调⽤ mark 之后记录所有读取的字节
并时刻准备在调⽤⽅法 reset 时(⽆论何时),再次提供这些相同的字节
但是,如果在调⽤ reset 之前可以从流中读取多于 readlimit 的字节,则不需要该流记录任何数据