天天看点

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕。

本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法。

ByteArrayInputStream 是字节数组输入流。它继承于InputStream。

它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的。

我们都知道,InputStream通过read()向外提供接口,供它们来读取字节数据;而ByteArrayInputStream 的内部额外的定义了一个计数器,它被用来跟踪 read() 方法要读取的下一个字节。

InputStream 函数列表

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

ByteArrayInputStream 函数列表

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

InputStream是ByteArrayInputStream的父类,我们先看看InputStream的源码,然后再学ByteArrayInputStream的源码。

1. InputStream.java源码分析(基于jdk1.7.40)

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

2. ByteArrayInputStream.java源码分析(基于jdk1.7.40)

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

说明:

ByteArrayInputStream实际上是通过“字节数组”去保存数据。

(01) 通过ByteArrayInputStream(byte buf[]) 或 ByteArrayInputStream(byte buf[], int offset, int length) ,我们可以根据buf数组来创建字节流对象。

(02) read()的作用是从字节流中“读取下一个字节”。

(03) read(byte[] buffer, int offset, int length)的作用是从字节流读取字节数据,并写入到字节数组buffer中。offset是将字节写入到buffer的起始位置,length是写入的字节的长度。

(04) markSupported()是判断字节流是否支持“标记功能”。它一直返回true。

(05)

mark(int

readlimit)的作用是记录标记位置。记录标记位置之后,某一时刻调用reset()则将“字节流下一个被读取的位置”重置到“mark(int

readlimit)所标记的位置”;也就是说,reset()之后再读取字节流时,是从mark(int readlimit)所标记的位置开始读取。

关于ByteArrayInputStream中API的详细用法,参考示例代码(ByteArrayInputStreamTest.java):

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

运行结果:

ArrayLetters=abcdefghijklmnopqrstuvwxyz

0 : 0x61

1 : 0x62

2 : 0x63

3 : 0x64

4 : 0x65

str1=klmno

str2=fghij

结果说明:

(01) ArrayLetters 是字节数组。0x61对应的ASCII码值是a,0x62对应的ASCII码值是b,依次类推...

(02) ByteArrayInputStream bais = new ByteArrayInputStream(ArrayLetters); 这句话是创建“字节流bais”,它的内容就是ArrayLetters。

(03) for (int i=0; i<LEN; i++) ; 这个for循环的作用就是从字节流中读取5个字节。每次调用bais.read()就从字节流中读取一个字节。

(04) bais.mark(0); 这句话就是“设置字节流的标记”,此时标记的位置对应的值是0x66。

(05) bais.skip(5); 这句话是跳过5个字节。跳过5个字节后,对应的字节流中下一个被读取的字节的值是0x6B。

(06) bais.read(buf, 0, LEN); 这句话是“从字节流中读取LEN个数据写入到buf中,0表示从buf的第0个位置开始写入”。

(07) bais.reset(); 这句话是将“字节流中下一个被读取的位置”重置到“mark()所标记的位置”,即0x66。

学完了ByteArrayInputStream输入流。下面,我们学习与之对应的输出流ByteArrayOutputStream。