[六]JavaIO之 ByteArrayInputStream与ByteArrayOutputStream
程序员文章站
2022-04-09 18:42:39
ByteArrayInputStream与ByteArrayOutputStream 类的详细介绍,以及读写方法的介绍 ......
功能简介
bytearrayinputstream 和 bytearrayoutputstream
提供了针对于字符数组 byte [] 的标准的io操作方式
bytearrayinputstream将会给一个byte buf[] 提供标准的io操作方式
bytearrayoutputstream则是将数据写入到内部的字节数组中
bytearrayinputstream 详解
功能: 从提供的字节数组中,以io的行为方式工作,进行读取数据
bytearrayinputstream字段
protected byte[] buf | 用于保存由该流的创建者提供的 byte 数组 也就是构造方法传入 |
protected int count | 个数 |
protected int mark | 流中当前的标记位置 构造时默认将 bytearrayinputstream 对象标记在位置零处 通过 mark() 方法可将其标记在缓冲区内的另一个位置处 通过 reset() 方法将当前缓冲区位置设置为此点 protected int mark = 0;定义时设置了默认值,如果不设置将为0 |
protected int pos | 要从输入流缓冲区中读取的下一个字符的索引 |
bytearrayinputstream构造方法
public bytearrayinputstream(byte[] buf) |
需要传入byte buf[] 字节数组作为他的缓冲区 当前起始下标 pos 为0 count为数组长度 mark位置为0 |
public bytearrayinputstream(byte[] buf,
int offset,
int length)
|
传入字节数组以及偏移量和长度 当前起始下标 pos 为 指定的偏移量 个数为offset+length 和 buf.length中小的那个 mark为偏移量起始地址 可以理解为,这个字节数组偏移量的部分才是数据源,前面都没关系 |
read方法
读取下一个位置的字节 如果下一个位置 pos小于总个数 返回pos下标的字节数组数据 并且pos自增 |
& 0xff : java中只有 有符号数,类型提升时是按照符号位扩展的 对于正数,没有什么影响 对于负数,按照符号位扩展和按照0位扩展区别很大 按符号位扩展,也就是补符号位,值不变 按零位扩展,也就是补零时,相当于有符号数转变为无符号数 所以在数值计算中,直接使用类型提升,数值不变 而对于编解码时,需要进行转换 &0xff这种方式就是来确保是按补零扩展 0xff默认为int型,是十六进制,十进制中表示为255,二进制为32位,后八位为'1111 1111',其他24位均为0 a & 0xff 操作时,因为a为byte型,所以会将a自动转化为int型(高位补1) byte & 0xff操作一般将byte数据转换成int型,最终的数据只有低8位有数据,其他位为0 |
简单说就是读取pos下标的元素,返回值为int |
带参数的read()方法 将数据读取到b的off位置处
//从流中读取数据到b[] 中,从off开始写,写len长度 public synchronized int read(byte b[], int off, int len) { if (b == null) {//如果b为null 空指针 throw new nullpointerexception(); } else if (off < 0 || len < 0 || len > b.length - off) {//如果偏移量小于0 或者写入长度小于0 或者想要读取的长度小于实际的长度了 throw new indexoutofboundsexception(); } if (pos >= count) {//如果位置光标已经到了最后了,没有数据可读,返回-1 return -1; } int avail = count - pos;//可用个数为总个数count - 当前位置pos if (len > avail) {//如果想要读取的len比实际拥有的数据要长,那么只读取实际的个数 len = avail; } if (len <= 0) { return 0; } system.arraycopy(buf, pos, b, off, len);//使用本地方法拷贝数据 buf 的pos位置开始拷贝,拷贝len个,到b的off位置 pos += len;//位置光标后移 return len; }
|
read方法本质很简单
就是一个数组,读取一个,就光标移动下一个,pos就是记住位置的变量
读取的就是指定下标的元素
skip
available
本质就是个数组,所以可用个数就是总个数减去下一个字符的索引 |
mark /marksupported /reset
bytearrayinputstream支持mark和reset 而且 很显然,mark方法的输入参数是无效的 何处调用,何处就是标记点 调用reset就是pos设置到标记点 |
为什么mark 的参数无效? 很显然,bytearrayinputstream是操作字符数组的,而且,这个数组不是复制而来的 是直接通过引用指向的 也就是说整个的字节数组都在随时可访问的范围内,要这个参数有什么用呢 mark /marksupported /reset 三连的本质在于提供可重复读的功能,所以对于不可逆的流需要缓存 此处天然自带可以随时读取某个下标的能力 |
close
bytearrayinputstream的根本在于针对给定的某个字节数组,提供io操作方式的统一形式 就好像你写了个方法操作字节数组一样,完全不涉及资源 所以无需关闭任何实质内容 |
通过close关闭bytearrayinputstream之后,如果再次使用这个流 并不会抛出异常 当然,流结束了,就不能再继续使用了 |
所有方法列表
bytearrayoutputstream详解
以io的行为方式工作,将数据写入到内部的字节数组中
bytearrayoutputstream字段
protected byte buf[]; |
存储数据的缓冲区 |
protected int count; |
缓冲区中的有效字节数,每次写入将会写入到buf[count]处 |
bytearrayoutputstream构造方法
构造方法只是设置内部字节数组这个缓冲区数据的大小
public bytearrayoutputstream() ;
|
默认长度为32位 |
public bytearrayoutputstream(int size) |
只要参数值合法,创建指定个数的字节数组缓冲区 |
write
write是输出,参数都是他的输出内容,只是不同的流输出的目的不一样,此处我们的输出流的目的地是内部的字节数组
write(int) | 将指定的字节写入此 byte 数组输出流 也就是写入到内部的字节数组中 |
write(byte[], int, int) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte 数组输出流 也就是写入到内部的字节数组中 |
可以看得出来,他们都有使用 ensurecapacity在必要的时候进行扩展
扩展的行为是新建一个更大的,然后将原有数组元素全部拷贝过去
保证空间足够的情况下
write(int) 就是buf[count] = (byte)b;
对于write(byte[], int, int) 则是使用system.arraycopy
writeto(outputstream)
因为bytearrayoutputstream内部维护的是一个字节数组,所以可以直接作为outputstream中write()方法的参数 代码很简单,就是讲内部的字节数组,转存到入参指定的输出流中 相当于把流中的数据重写了一份到另外的输出流 |
tostring()
计算机所有的数据都是二进制存储,最小的单位是字节,字符的编码形式也正是字节 所以,tostring其实就是把字节序列进行解码 |
int类型入参的方法,在jdk1.8 已经弃用 |
tostring()使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串
tostring(string charsetname) 使用指定的 charsetname,通过解码字节将缓冲区内容转换为字符串
|
reset()
reset是重置的意思,bytearrayoutputstream 使用buf[] 存储数据,使用count指示位置 所以想要重新使用现在的缓冲区,抛弃原来所有的,只需要将count清零,每次的数据重新从0开始写入字节数组即可 |
反正我们知道现在总共有多少有效字节,原来写入到buf中的可能多于count的那些字节就放着好了,我们也不去使用 |
size()
count就是一直用来记录有效个数的,所以直接返回count就是实际的size |
tobytearray()
转换为字节数组,它本身就是一个字节数组 所以转换比较简单,只需要创建一个大小相同的字节数组,并且将数据拷贝过去即可 |
close()
bytearrayoutputstream 写入的是自己内部的字节数组 属于内存数据,不涉及任何资源,所以close不需要做什么 |
上一篇: 幽默谈感情,谈出点笑容
下一篇: java验证码的制作和验证
推荐阅读
-
ASP讲座之六:ASP与数据库(一)
-
Vuejs第六篇之Vuejs与form元素实例解析
-
(六) mybatis 源码之 四大对象与插件开发
-
靖难六国公与靖难之役有什么关联?他们的生命轨迹有何不同?
-
query简单入门到精通细节 - (六)Jquery效果之“淡入与淡出”
-
前端(六)之盒模型显隐、定位与流式布局思想
-
[六]JavaIO之 ByteArrayInputStream与ByteArrayOutputStream
-
以太坊源码分析之 P2P网络(六、p2p连接控制与消息处理(下))
-
[二十一]JavaIO之BufferedReader 与 BufferedWriter
-
MySQL系列之六 用户与授权