java.io.ByteArrayOutputStream 源码分析

成员变量 buf是存储数据的缓冲区
 count是缓冲区中的有效字节数。


    /**
* The buffer where data is stored.
*/
protected byte buf[];

/**
* The number of valid bytes in the buffer.
*/
protected int count;

构造参数
默认值32,也可以指定缓冲区到大小


    /**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public ByteArrayOutputStream() {
this(32);
}

/**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @exception IllegalArgumentException if size is negative.
*/
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}

检查容量是否够用,不够则进行扩容grow。

    private void ensureCapacity(int minCapacity) {
// overflow-conscious code
if (minCapacity - buf.length > 0)
grow(minCapacity);
}

根据所需要到缓冲区大小重新设置缓冲区。


    private void grow(int minCapacity) {
//记录旧到缓冲区大小
int oldCapacity = buf.length;
//这里是移位运算 相当于 int newCapacity = oldCapacity X 2;
int newCapacity = oldCapacity << 1;
//如果2倍的大小仍然不够,直接将minCapacity设置为缓冲区大小
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity < 0) {
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;
}


    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;
}

将缓冲区内容写到输出流当中

     public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}

返回缓冲区内容

    public synchronized byte toByteArray()[] {
return Arrays.copyOf(buf, count);
}

时间: 2024-12-20 16:40:02

java.io.ByteArrayOutputStream 源码分析的相关文章

java.io.BufferedOutputStream 源码分析

BufferedOutputStream  是一个带缓冲区到输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统. 俩个成员变量,一个是存储数据的内部缓冲区,一个是缓冲区中的有效字节数. /** * The internal buffer where data is stored. */ protected byte buf[]; /** * The number of valid bytes in the buffer. This value

java.io.ByteArrayInputStream 源码分析

您还未登录 ! 登录 注册 论坛首页 → Java企业应用论坛 →  深入理解HashMap 全部 Hibernate Spring Struts iBATIS 企业应用 Lucene SOA Java综合 Tomcat 设计模式 OO JBoss ? 上一页 1 2 3 - 8 9 下一页 ? 浏览 65519 次 锁定老帖子 主题:深入理解HashMap 该帖已经被评为精华帖 作者 正文 annegu 等级:  性别:  文章: 38 积分: 360 来自: 杭州 发表时间:2009-12-

Java split方法源码分析

Java split方法源码分析 1 public String[] split(CharSequence input [, int limit]) { 2 int index = 0; // 指针 3 boolean matchLimited = limit > 0; // 是否限制匹配个数 4 ArrayList<String> matchList = new ArrayList<String>(); // 匹配结果队列 5 Matcher m = matcher(inp

【JAVA】ThreadLocal源码分析

ThreadLocal内部是用一张哈希表来存储: 1 static class ThreadLocalMap { 2 static class Entry extends WeakReference<ThreadLocal<?>> { 3 /** The value associated with this ThreadLocal. */ 4 Object value; 5 6 Entry(ThreadLocal<?> k, Object v) { 7 super(k)

Java中ArrayList源码分析

一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保证容量能容纳所有数据. 1.1.ArrayList 的继承与实现接口 ArrayList继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口. public class  ArrayList<E> ex

Java笔记---ArrayList源码分析

一.前言 一直就想看看java的源码,学习一下大牛的编程.这次下狠心花了几个晚上的时间,终于仔细分析了下 ArrayList 的源码(PS:谁说的一个晚上可以看完的?太瞎扯了).现在记录一下所得. 二.ArrayList 源码分析 2.1 如何分析? 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 Eclipse 找到所需要分析的类(此处就是 ArrayList) 新建类:新建一个类,命名为 ArrayList,将源码拷贝到该类.因为我

Java并发包源码分析

并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多个核,是否能合理运用多核的能力将成为一个大规模应用程序的关键. Java基础部分知识总结点击Java并发基础总结.Java多线程相关类的实现都在Java的并发包concurrent,concurrent包主要包含3部分内容,第一个是atomic包,里面主要是一些原子类,比如AtomicInteger.

Java - &quot;JUC&quot; Semaphore源码分析

Java多线程系列--"JUC锁"11之 Semaphore信号量的原理和示例 Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量中有可用的许可时,线程能获取该许可:否则线程必须等待,直到有可用的许可为止. 线程可以通过release()来释放它所持有的信号量许可. Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的Reent

Java之set源码分析

Java的集合类由Collection接口和Map接口派生,其中: List代表有序集合,元素有序且可重复 Set代表无序集合,元素无序且不可重复 Map集合存储键值对 那么本篇文章将从源码角度讨论一下无序集合Set. HashSet HashSet实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持.它不保证 set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用 null 元素.看下面的一个例子: HashSet<String> hs = new HashSet&