ByteArrayInputStream是字节输入流,继承自InputStream,内部将一个字节数组作为内部缓冲区,通过read()方法供外界读取字节,同时包含一个成员变量count用来计数累加,count跟着ByteArrayInputStream中read()方法的下一个字节。

ByteArrayInputStream源码

package java.io;public class ByteArrayInputStream extends InputStream {//内部缓冲区,保存字节输入流数据protected byte buf[];//下一个被读取字节的位置,随着read()方法累加protected int pos;//标记位置使用,配合reset()使用,reset()调用会回到上一次标记的位置protected int mark = 0;//字节流长度protected int count;public ByteArrayInputStream(byte buf[]) {this.buf = buf;this.pos = 0;this.count = buf.length;}public ByteArrayInputStream(byte buf[], int offset, int length) {this.buf = buf;this.pos = offset;this.count = Math.min(offset + length, buf.length);this.mark = offset;}//读取当个字节,pos累加public synchronized int read() {return (pos < count) ? (buf[pos++] & 0xff) : -1;}//经过一些列的判断,将字节流中的数据存储到b数组中,//offset表示偏移量,即从off的位置开始取数据//len表示字节长度,真正取到的字符off位置开始的len个字节public synchronized int read(byte b[], int off, int len) {if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();}if (pos >= count) {return -1;}int avail = count - pos;if (len > avail) {len = avail;}if (len <= 0) {return 0;}System.arraycopy(buf, pos, b, off, len);pos += len;return len;}//跳过n个字节public synchronized long skip(long n) {long k = count - pos;if (n < k) {k = n < 0 ? 0 : n;}pos += k;return k;}//判断下个存在下个字节public synchronized int available() {return count - pos;}public boolean markSupported() {return true;}//标记当前位置public void mark(int readAheadLimit) {mark = pos;}//重置“字节流的读取索引”为“mark所标记的位置”public synchronized void reset() {pos = mark;}public void close() throws IOException {}
}

ByteArrayOutputStream是字节输出流,数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

ByteArrayOutputStream源码:

package java.io;import java.util.Arrays;public class ByteArrayOutputStream extends OutputStream {//内部缓冲数组,存放字节protected byte buf[];//当前存放的字节量protected int count;//默认容量为32public ByteArrayOutputStream() {this(32);}public ByteArrayOutputStream(int size) {if (size < 0) {throw new IllegalArgumentException("Negative initial size: "+ size);}buf = new byte[size];}//检测需否需要扩容,若缓冲数组大小大于扩容的大小,扩容private void ensureCapacity(int minCapacity) {if (minCapacity - buf.length > 0)grow(minCapacity);}//扩容操作private void grow(int minCapacity) {int oldCapacity = buf.length;//新容量为旧容量的2倍int newCapacity = oldCapacity << 1;if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity < 0) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();newCapacity = Integer.MAX_VALUE;}buf = Arrays.copyOf(buf, newCapacity);}//逐个写入字节public synchronized void write(int b) {ensureCapacity(count + 1);buf[count] = (byte) b;count += 1;}//将b中字节写入到缓冲数组中,off表示b中写入位置的偏移量,len为需要写入的字节量public synchronized void write(byte b[], int off, int len) {if ((off < 0) || (off > b.length) || (len < 0) ||((off + len) - b.length > 0)) {throw new IndexOutOfBoundsException();}ensureCapacity(count + len);System.arraycopy(b, off, buf, count, len);count += len;}// 写入输出流out到“字节数组输出流”中。public synchronized void writeTo(OutputStream out) throws IOException {out.write(buf, 0, count);}//重置public synchronized void reset() {count = 0;}//转化为字节数组public synchronized byte toByteArray()[] {return Arrays.copyOf(buf, count);}public synchronized int size() {return count;}public synchronized String toString() {return new String(buf, 0, count);}public synchronized String toString(String charsetName)throws UnsupportedEncodingException{return new String(buf, 0, count, charsetName);}@Deprecatedpublic synchronized String toString(int hibyte) {return new String(buf, hibyte, 0, count);}public void close() throws IOException {}
}

具体应用

 byte[] array = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','z','y','z'};ByteArrayOutputStream baos = null;ByteArrayInputStream bais = null;try {baos = new ByteArrayOutputStream();//将array写入到baos缓冲数组中baos.write(array);System.out.println("baos = "+baos);//baos = abcdefghijklmnopqrstuvwzyz//重置baos,此时内部的count值为0baos.reset();System.out.println("reset baos = "+baos);//reset baos = //将array中5-20位置的字节写入到baos缓冲数组中baos.write(array, 5, 15);System.out.println("offset baos = "+baos);//offset baos = fghijklmnopqrst//bais中缓冲数组为fghijklmnopqrstbais = new ByteArrayInputStream(baos.toByteArray());int count = 0;StringBuilder str = new StringBuilder();//循环逐个读取字节,知道返回值为-1,即表示字节白被读完while((count = bais.read())!=-1) {//获取到的count是ascii码,强转为charstr.append((char) count);}System.out.println("str = "+str.toString());//str = fghijklmnopqrst//bais中缓冲数组为fghijklmnopqrstbais = new ByteArrayInputStream(baos.toByteArray());//将bais中缓存数组的0-5的字节,读入到array中,即将abcde更改为fghijbais.read(array, 0, 5);String str1 = new String(array);System.out.println("str1 = "+str1);//str1 = fghijfghijklmnopqrstuvwzyz//标记第5个位置bais.mark(5);//将内部的pos设置为刚设置的5bais.reset();//将bais中缓存数组的0-5的字节,读入到array中,即将fghij更改为klmnobais.read(array, 0, 5);String str2 = new String(array);System.out.println("str2 = " +str2);//str1 = klmnofghijklmnopqrstuvwzyz} catch (IOException e) {e.printStackTrace();}finally {try {if(bais!=null)bais.close();if(baos!=null)baos.close();} catch (IOException e) {e.printStackTrace();}}

Java基础IO系列之ByteArrayInputStream和ByteArrayOutputStream解析相关推荐

  1. # Java基础——IO流

    Java基础--IO流 File类的使用(熟悉构造器和方法的使用) File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹) File类的声明在java.io包下 文件和文件目录路径的抽象表示 ...

  2. Java基础-IO流对象之数据流(DataOutputStream与DataInputStream)

    Java基础-IO流对象之数据流(DataOutputStream与DataInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据流特点 操作基本数据类型 ...

  3. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  4. Java基础IO流(二)字节流小案例

    JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...

  5. 【Java基础巩固系列】高级Java进阶之最全面技术架构思维导图

    热门系列: [Java基础巩固系列]Java数据集合,List.Map.Set.JUC,应有尽有 [Java基础巩固系列]Java内存溢出和内存泄漏 [Java基础巩固系列]Java类初始化执行顺序 ...

  6. Java基础IO流之字符流的使用

    ☆引言☆ 大家好,我是痛而不言笑而不语的浅伤.IO流分为字节流和字符流,而上一篇文章我们学习了字节流(Java基础IO流之字符流的使用),这篇文章带大家一起来学习字符流吧.对文章中描述错误的希望大家积 ...

  7. Java基础之equals和==的区别深入解析

    Java基础之equals和==的区别深入解析 以下是本文目录大纲 equals 和 == 的区别 equals 的重写 复写hashCode方法,有31这个数字的作用 1. equals 和 == ...

  8. 黑马程序员——Java基础--IO流(一)---File类以及其他流对象

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.File类 File类是将文件系统中的文件和文件夹封装成了对象.提供了更多的属性和行为可以对 ...

  9. Java基础—IO流(三)

    IO流(三) File类 一.概述 File类用于将文件或文件夹封装成对象,方便对文件和文件夹的属性信息进行操作.该类可以作为参数传递给IO流的构造函数,弥补流对象在操作文件和文件夹上的缺陷. 二.F ...

最新文章

  1. VC 下 64bit 整数的显示和读取格式化字串
  2. 解决Python自带的json序列化工具不能序列化datetime类型数据问题
  3. [ExtJS5学习笔记]第十节 Extjs5新增特性之ViewModel和DataBinding
  4. mysql学习笔记01-创建数据库
  5. 1451C. String Equality
  6. 动态规划——最长公共子序列(算法设计课题)
  7. 京东物流将收购德邦股份66.49%股份
  8. 自顶向下红黑树java,【CPP】各种各样的树(9)——自顶向下的红黑树
  9. 我为啥不想用Python
  10. oracle中使用kill,WINDOWS和LINUX服务器级别的KILLORACLE进行方法
  11. 艰难前行的故事 (《梦断代码》读后感)
  12. Linux 下 4 种禁用 Root 登陆的方法,你掌握了哪几种呢?
  13. 985大学计算机专业保研率排名,2016中国大学保研率排行榜出炉
  14. Atitit. atiOrder   Order 订单管理框架的设计
  15. Dell Optiplex主流台式机驱动安装指南
  16. java structs_java深入探究12-框架之Structs
  17. 硬件知识——主板结构
  18. [DAX] MAX函数 | MAXX函数
  19. 哈迪-温伯格平衡(Hardy-Weinberg equilibrium)法则
  20. Python做一个简单的名片管理系统

热门文章

  1. 我发现凡是给offer的公司,面试时基本不问技术细节,那些问得又多又细的公司,后面就没下文了!
  2. 第一波开源年报开发者问卷中奖名单新鲜出炉!
  3. PyQt5 QTableWidget 删除所有行
  4. 上饶师范学院数学与计算机科学学院,第4章-上饶师范学院数学与计算机科学学院.doc...
  5. 【嵌入式05】Ubuntu下opencv新手操作:(打开图片及视频)
  6. Mac终端加入IDEA命令
  7. cmd窗口输入python跳转到微软商店
  8. 如何将最大化互信息引入到无监督域适应(UDA)任务?
  9. symbian学习转载
  10. 聚划算火拼如何参团 聚划算火拼效果怎么样