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

 

posted on 2021-10-19 17:56  icodegarden  阅读(6352)  评论(0编辑  收藏  举报