Java中IO框架——ByteArrayOutputStream源码解析

ByteArrayOutputStream 继承自 OutputStream 。
OutputStream 的源码分析见:http://blog.csdn.net/yx0628/article/details/79370689
同时可以参考 ByteArrayInputStream 的源码:http://blog.csdn.net/yx0628/article/details/79346595

此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException 。

属性

    // 缓冲字节数组,数据写入这里
    protected byte buf[];
    // 字节数组中的有效字节个数
    protected int count;
    // 数组最大容量值(和ArrayList的数组最大值同样道理)
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

构造函数

    // 创建一个新的字节数组输出流
    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) {
        // 如果需要的最小容量大于数组的容量,那么调用grow函数来扩展
        // 否则,不需要改变这个数组的大小
        if (minCapacity - buf.length > 0)
            grow(minCapacity);
    }

    // 扩张容量
    private void grow(int minCapacity) {
        // 保存当前的数组大小
        int oldCapacity = buf.length;
        // 新的大小将旧大小扩张二倍
        int newCapacity = oldCapacity << 1;
        // 此时判断新容量和所需容量,如果新容量还不满足要求,使用所需容量作为新容量
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 然后比较新容量和最大容量,如果新容量大于最大容量,调用hugeCapacity方法
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 将旧数组中所有字节拷贝到新容量大小的新数组中,这个新数组作为新的缓冲字节数组
        buf = Arrays.copyOf(buf, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        // 如所需容量大于最大容量,那么就使用最大整数,否则就使用最大容量即可
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

write(int b)

    // 同步方法,写入一个字节
    public synchronized void write(int b) {
        // 调用ensureCapacity函数确保count位置有空间可以写入
        // count由于是已存在有效字节的个数,比如count为10,代表数组中0-9这10个位置有字节
        // 如果数组容量就是10,那么count下标即10的下标是越界的,所以要进行判断
        // 这里要么有空间直接能写入,要么扩张大小后写入字节
        ensureCapacity(count + 1);
        // 将字节写入count下标处
        buf[count] = (byte) b;
        // 有效字节数count加1
        count += 1;
    }

write(byte b[], int off, int len)

    // 同步方法,从给定的字节数组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)) {
            // 偏移量off及个数len应该满足的条件,否则抛出范围异常
            throw new IndexOutOfBoundsException();
        }
        // 确保空间是否需要增长len的长度
        ensureCapacity(count + len);
        // 数组拷贝,b数组off下标开始拷贝到buf数组count下标处,共len个字节
        System.arraycopy(b, off, buf, count, len);
        // 元素个数count增加len个
        count += len;
    }

writeTo(OutputStream out)

将此 byte 数组输出流的全部内容写入到指定的输出流。

    // 这里是将当前字节数组流的字节数组的所有字节,写入到目标输出流中
    public synchronized void writeTo(OutputStream out) throws IOException {
        out.write(buf, 0, count);
    }

reset()

    public synchronized void reset() {
        // 将count置为0,代表字节数组中的字节都要丢弃
        count = 0;
    }

byte toByteArray()[]

    public synchronized byte toByteArray()[] {
        // 创建一个新分配的byte数组
        // 其大小是此输出流的当前大小,并且缓冲区的有效内容已复制到该数组中。
        return Arrays.copyOf(buf, count);
    }

size()

    public synchronized int size() {
        // 返回字节数组中有效字节的个数
        return count;
    }

toString

    // 使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。
    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);
    }

close()

关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException 。

    // close方法未实现具体行为
    public void close() throws IOException {
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值