1.ByteArrayInputStream和ByteArrayOutputStream简介
ByteArrayInputStream是字节数组输入流,继承InputStream,它里面维护一个缓冲区,也就是一个byte类型的数组,通过一个计数器pos来实现对字节数组的读取。与之相对应的ByteArrayOutputStream是字节数组输出流,继承自OutputStream,它里面也维护一个缓冲区,通过一个计数器count来实现对字节数组的操作。具体实现如下
2.ByteArrayInputStream源码分析
package java.io;
public class ByteArrayInputStream extends InputStream {
//字节缓冲区
protected byte buf[];
//当前读取字节的位置
protected int pos;
//标记字节的位置,如果没有标记,则为0
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() {
//如果当前pos的位置的值超过了byte的最大的值,则和0xff与运算,获取正值
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
//把当前字节流里面的数据读取到传入的字节数组中
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;
//如果写入b的长度大于当前缓冲区的大小,则更新写入的长度为当前缓冲区的大小
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
//调用native方法把当前缓冲区的内容复制到b中
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
//跳过指定的字节大小,如果当前跳过的大小大于剩余的字节的数量,则跳过剩余字节的数量
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;
}
//重置当前流到标记的位置开始读取
public synchronized void reset() {
pos = mark;
}
//该字节流在内存中操作,不需要关闭
public void close() throws IOException {
}
}
3.ByteArrayOutputStream源码分析
package java.io;
import java.util.Arrays;
public class ByteArrayOutputStream extends OutputStream {
//缓冲区
protected byte buf[];
//当前缓冲区存储字节的数量
protected int count;
//初始化默认的字节流的缓冲大小为32
public 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) {
// overflow-conscious code
//如果当前缓冲区的大小不能继续存放字节,则扩容
if (minCapacity - buf.length > 0)
grow(minCapacity);
}
//字节流缓冲扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = buf.length;
int newCapacity = oldCapacity << 1;
//最小扩容为原来的一倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity < 0) {//超过Integer的大小,则变为负数
if (minCapacity < 0) // overflow
throw 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开始写入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;
}
//把一个outputStream中存储的数据写入到当前字节流数组
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
//重置字节流数组的读取的位置为0
public synchronized void reset() {
count = 0;
}
//把字节流转换成字节数组
public synchronized byte toByteArray()[] {
return Arrays.copyOf(buf, count);
}
//返回当前字节流数组读取的位置
public synchronized int size() {
return count;
}
//根据默认的字节编码来把字节流转换成string
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);
}
@Deprecated
public synchronized String toString(int hibyte) {
return new String(buf, hibyte, 0 count);
}
//因为在内存中操作,所以不需要关闭流
public void close() throws IOException {
}
}
4.示例代码
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class ByteTest {
private static final String STRING1 = "成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。";
public static void main(String[] args) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(STRING1.getBytes());
byte[] buffer = new byte[STRING1.getBytes().length];
byte[] bytes = new byte[1024];
int count;
int readCount=0;
while((count=bis.read(bytes)) > 0)
{
System.arraycopy(bytes, 0, buffer, readCount, count);
readCount += count;
}
System.out.println(new String(buffer,"utf-8"));
System.out.println("============================");
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
byte[] buffer2 = STRING1.getBytes();
bos.write(buffer2,0,buffer2.length);
//System.out.println(bos.toString("utf-8"));
System.out.println(new String(bos.toByteArray(),"utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。
============================
成功后,进一步的元素处理被抑制,并且搜索功能的任何其他并行调用的结果被忽略。