[六]JavaIO之 ByteArrayInputStream与ByteArrayOutputStream
功能简介

ByteArrayInputStream 详解
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这种方式就是来确保是按补零扩展 |
简单说就是读取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; } |

skip
![]() |
![]() |
available
本质就是个数组,所以可用个数就是总个数减去下一个字符的索引![]() |
mark /markSupported /reset
ByteArrayInputStream支持mark和reset 而且 很显然,mark方法的输入参数是无效的 何处调用,何处就是标记点 调用reset就是pos设置到标记点 |
![]() |
为什么mark 的参数无效? 很显然,ByteArrayInputStream是操作字符数组的,而且,这个数组不是复制而来的 是直接通过引用指向的 也就是说整个的字节数组都在随时可访问的范围内,要这个参数有什么用呢 mark /markSupported /reset 三连的本质在于提供可重复读的功能,所以对于不可逆的流需要缓存 此处天然自带可以随时读取某个下标的能力 |
close
ByteArrayInputStream的根本在于针对给定的某个字节数组,提供IO操作方式的统一形式 就好像你写了个方法操作字节数组一样,完全不涉及资源 所以无需关闭任何实质内容 |
通过close关闭ByteArrayInputStream之后,如果再次使用这个流 并不会抛出异常 当然,流结束了,就不能再继续使用了 |

ByteArrayOutputStream详解
ByteArrayOutputStream字段
protected byte buf[]; | 存储数据的缓冲区 |
protected int count; | 缓冲区中的有效字节数,每次写入将会写入到buf[count]处 |
ByteArrayOutputStream构造方法
public ByteArrayOutputStream() ;
|
默认长度为32位![]() |
public ByteArrayOutputStream(int size) | 只要参数值合法,创建指定个数的字节数组缓冲区![]() |
write
write(int) | 将指定的字节写入此 byte 数组输出流 也就是写入到内部的字节数组中 |
write(byte[], int, int) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte 数组输出流 也就是写入到内部的字节数组中 |

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不需要做什么 |
![]() |
[六]JavaIO之 ByteArrayInputStream与ByteArrayOutputStream的更多相关文章
- FileInputstream,FileOutputstream 和 byteArrayInputStream,byteArrayOutputStream
你知道FileInputstream和FileOutputstream吗?FileInputstream,FileOutputstream分别是由抽象类Inputstream和Outputstream ...
- Java IO(七)ByteArrayInputStream 和 ByteArrayOutputStream
Java IO(七)ByteArrayInputStream 和 ByteArrayOutputStream 一.介绍 ByteArrayInputStream 和 ByteArrayOutputSt ...
- Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream
类的继承关系 InputStream |__ ByteArrayInputStream OutputStream |__ ByteArrayOutputStream ByteArrayInputStr ...
- [二十六]JavaIO之再回首恍然(如梦? 大悟?)
流分类回顾 本文是JavaIO告一段落的总结帖 希望对JavaIO做一个基础性的总结(不涉及NIO) 从实现的角度进行简单的介绍 下面的这两个表格,之前出现过 数据源形式 InputStream Ou ...
- ByteArrayInputStream和ByteArrayOutputStream
public class ByteArrayTest { public static void main(String[] args) throws IOException { read(write( ...
- ByteArrayInputStream 和 ByteArrayOutputStream
package java.io; /** * A <code>ByteArrayInputStream</code> contains * an internal buffer ...
- 黑马程序猿 IO流 ByteArrayInputStream与ByteArrayOutputStream
---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- package cn.itcast.IO; i ...
- Java之IO(三)ByteArrayInputStream和ByteArrayOutputStream
转载请注明源出处:http://www.cnblogs.com/lighten/p/6972297.html 1.前言 这组输入输出流比较特殊,一般的流指定都是磁盘IO和网络IO,从文件中读取数据或者 ...
- java io流 数据流 DataInputStream、DataOutputStream、ByteArrayInputStream、ByteArrayOutputStream
例子程序: package io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ...
随机推荐
- go http
先看一个简单的 tcp 连接: // server ln, err := net.Listen("tcp", ":8000") if err != nil {} ...
- mysql_Navicat数据库破解
Navicat Premium 12.1.16.0安装与激活 Navicat Premium 12是一套数据库开发管理工具,支持连接 MySQL.Oracle等多种数据库,可以快速轻松地创建.管理和维 ...
- 马昕璐/唐月晨 《面向对象程序设计(java)》第十一周学习总结
一:理论部分. 一般将数据结构分为两大类:线性数据结构和非线性数据结构 线性数据结构:线性表.栈.队列.串.数组和文件 非线性数据结构:树和图. 线性表:1.所有数据元素在同一个线性表中必须是相同的数 ...
- CSS面试细节整理(二)
5.css盒模型: CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边距.边框 和 外边距 的方式
- 排列组合python
python 的 itertools模块 可以专业的处理的排列组合问题 写在自己博客里,怕下次找不到喽
- 高德Location
1.创建Demo,获取key 打开高德开发平台 → 我的应用 → 创建应用 → 创建新Key 说明: 1.发布版安全码获取:用自己的签名打包成apk安装软件,用SHA1工具查看 2.调试版安全码获取: ...
- mysql 删除指定字符
mysql 删除指定字符 1.1 前言 实际需求中如果想删除指定的字符,一般需要使用到trim函数.trim函数默认删除字符的前后空格,如果想指定删除特定字符,则需要使用一下语句进行声明 ...
- [FPGA] 1、Artix-7 35T Arty FPGA 评估套件学习 + SiFive risc-v 指令集芯片验证
目录 1.简介 2.深入 3.DEMO 4.SiFive基于risc-v指令集的芯片验证 LINKS 时间 作者 版本 备注 2018-10-09 08:38 beautifulzzzz v1.0 到 ...
- travis-ci 中运行 puppeteer
通过 travis-ci 可以构建基于 puppeteer 的自动化任务,基于此构建的一个 计划任务 puppeteer中调用需要禁用沙箱环境 https://github.com/GoogleChr ...
- FFmpeg 结构体学习(三): AVPacket 分析
在上文FFmpeg 结构体学习(二): AVStream 分析我们学习了AVStream结构体的相关内容.本文,我们将讲述一下AVPacket. AVPacket是存储压缩编码数据相关信息的结构体.下 ...