FastByteArrayOutputStream
FastByteArrayOutputStream
性能版的ByteArrayOutputStream,跟ResizableByteArrayOutputStream不同的是他继承的是OutputStream。
使用ArrayDeque<byte[]>作为容器。
他性能高的原因在于写入新数据时,不会扩容byte[],而是向Deque增加byte[],每个byte[]在数据写入时就确定了大小,每个byte[]的大小有点预估性(每次乘以2递增),因为最后一个byte[]可能比较大,有一定的内存浪费。
private static final int DEFAULT_BLOCK_SIZE = 256; 默认每个byte[]的大小
private final Deque<byte[]> buffers = new ArrayDeque<>();
private final int initialBlockSize; 初始每个byte[]的大小
private int nextBlockSize = 0; 下一次创建byte[]的大小
private int alreadyBufferedSize = 0; 之前已存在的buffers里的所有byte[]的length累加
private int index = 0; buffers里的最好一个byte[]的当前写位置
private boolean closed = false; 当true时不能使用write,否则IOException
#public void write(int datum) throws IOException 写入一个字节(注意会强转为byte)。若队列最后1个 是null或已满,则addBuffer(1); 建一个新的byte[],最后把字节赋值给队列最后1个index++
#public void write(byte[] data, int offset, int length) throws IOException 写入byte[]。
##若队列最后1个 是null或已满,则addBuffer(length); 建一个新的byte[]
##若队列最后1个的index+待写入length > 队列最后1个的长度(剩余容量不够),do while(剩余待写入length > 0) 若队列最后1个的index == 队列最后1个的长度(已满),则addBuffer(length); ,取 队列最后1个的剩余容量 和 剩余待写入length 的较大值,copy待写入byte[]到队列最后1个,然后 剩余待写入length -= copyLength。这里使用do while的原因是addBuffer的大小是每次*2的,一次addBuffer可能不够。
##若到这里(剩余容量足够),直接copy需要写入的数据
#public void close() this.closed = true;
#public String toString() return new String(toByteArrayUnsafe());
#public int size() return (this.alreadyBufferedSize + this.index);
#public byte[] toByteArrayUnsafe() 先使用size得出totalSize,再使用resize(totalSize); ,最后取队列第一个(resize之后队列合并成一个)。由于返回的是内部byte[]引用,是不安全的,不要在得到后进行写操作。
#public byte[] toByteArray() 先使用toByteArrayUnsafe,则对得到的buye[]进行clone
#public void reset() 重置所有数据到初始。
#public InputStream getInputStream() return new FastByteArrayInputStream(this); 返回一个读取FastByteArrayOutputStream数据的InputStream , FastByteArrayInputStream是内部类
#public void writeTo(OutputStream out) throws IOException 把队列中的所有byte[]写到out
#public void resize(int targetCapacity) 重置队列成一个byte[],输入要求targetCapacity >= size()
##若队列第一个是null,nextBlockSize=targetCapacity
##否则若队列中只有1个byte[]且它的length==targetCapacity,表示无需resize
##否则使用targetCapacity新建一个byte[],把队列中所有byte[] copy到新的byte[],清空队列,把新byte[]放入队列
#private void addBuffer(int minCapacity) 以nextBlockSize的大小,向队列中新建一个byte[],nextBlockSize会以*2倍增
FastByteArrayInputStream extends UpdateMessageDigestInputStream
它的数据源是FastByteArrayOutputStream,遵循InputStream规范,不能再读时返回-1