ByteArrayOutputSTream是字节数组输出流,继承于OutputStream。ByteArrayOutputStream中的数据被写入到一个byte数组中,缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()获取数据。
ByteArrayOutputStream类主要的函数:
ByteArrayOutputStream()
ByteArrayOutputStream(int size)
void    close()
synchronized void    reset()
int     size()
synchronized byte[]  toByteArray()
String  toString(int hibyte)
String  toString(String charsetName)
String  toString()
synchronized void    write(byte[] buffer, int offset, int len)
synchronized void    write(int oneByte)
synchronized void    writeTo(OutputStream out)

ByteArrayOutputStream示例代码:

public class ByteArrayOutputStreamTest {

    private static final int LEN = 5;
    // 对应英文字母“abcddefghijklmnopqrsttuvwxyz”
    private static final byte[] ArrayLetters = {
        0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
    };

    public static void main(String[] args) {
        //String tmp = new String(ArrayLetters);
        //System.out.println("ArrayLetters="+tmp);

        tesByteArrayOutputStream() ;
    }

    /**
     * ByteArrayOutputStream的API测试函数
    */
    private static void tesByteArrayOutputStream() {
        // 创建ByteArrayOutputStream字节流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // 依次写入“A”、“B”、“C”三个字母。0x41对应A,0x42对应B,0x43对应C。
        baos.write(0x41);
        baos.write(0x42);
        baos.write(0x43);
        System.out.printf("baos=%s\n", baos);

        // 将ArrayLetters数组中从“3”开始的后5个字节写入到baos中。
        // 即对应写入“0x64, 0x65, 0x66, 0x67, 0x68”,即“defgh”
        baos.write(ArrayLetters, 3, 5);
        System.out.printf("baos=%s\n", baos);

        // 计算长度
        int size = baos.size();
        System.out.printf("size=%s\n", size);

        // 转换成byte[]数组
        byte[] buf = baos.toByteArray();
        String str = new String(buf);
        System.out.printf("str=%s\n", str);

        // 将baos写入到另一个输出流中
        try {
            ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
            baos.writeTo((OutputStream)baos2);
            System.out.printf("baos2=%s\n", baos2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
运行结果
baos=ABC

baos=ABCdefgh

size=8

str=ABCdefgh

baos2=ABCdefgh

源代码说明:
(1)ByteArrayOutputStream实际上是将字节数据写入到字节数组中去
(2)通过ByteArrayOutputStream()创建的字节数组输出流对应的字节数组的大小是32
(3)通过ByteArrayOutputStream(int size)创建字节数组输出流对应的字节数组大小是size
(4)write(int oneByte)的作用是将int类型的oneByte换成byte类型,然后写入到输出流中。
(5)write(byte[] buffer,int offset,int len)是将字节数组buffer写入到输出流中,offset是从buffer中读取数据的起始偏移位置,len是读取的长度
(6)writeTo(OutputStream out) 是将该字节数组输出流的数据全部写入到输出流out中

基于JDK8的源代码分析:

public class ByteArrayOutputStream extends OutputStream {

    /**
     * The buffer where data is stored.
     */
    //存储数据的缓冲区数组
    protected byte buf[];

    /**
     * The number of valid bytes in the buffer.
     */
    //缓冲数组中的有效字节数
    protected int count;

    /**
     * Creates a new byte array output stream. The buffer capacity is
     * initially 32 bytes, though its size increases if necessary.
     */
    //创建一个32大小的数组
    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.
     */
    //创建一个size大小的输出数组
    public ByteArrayOutputStream(int size) {
        if (size < 0) {
            throw new IllegalArgumentException("Negative initial size: "+ size);
        }
        buf = new byte[size];
    }

    /**
     * Increases the capacity if necessary to ensure that it can hold
     * at least the number of elements specified by the minimum
     * capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     * @throws OutOfMemoryError if {@code minCapacity < 0}.  This is
     * interpreted as a request for the unsatisfiably large capacity
     * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
     */
    //增大容量
    private void ensureCapacity(int minCapacity) {
    // overflow-conscious code
        if (minCapacity - buf.length > 0)
            grow(minCapacity);
    }

    /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    //最大的数组大小
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    //增大容量,先将之前的容量加倍,再判断是否需要使用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 - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        buf = Arrays.copyOf(buf, newCapacity);
    }
    //最大容量
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
    }

    /**
     * Writes the specified byte to this byte array output stream.
     *
     * @param   b   the byte to be written.
     */
    //写到输出数组中
    public synchronized void write(int b) {
        ensureCapacity(count + 1);
        buf[count] = (byte) b;
        count += 1;
    }

    /**
     * Writes <code>len</code> bytes from the specified byte array
     * starting at offset <code>off</code> to this byte array output stream.
     *
     * @param   b     the data.
     * @param   off   the start offset in the data.
     * @param   len   the number of bytes to write.
     */
    //从特定的数组b中写len长度,其实为offset
    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;
    }

    /**
     * Writes the complete contents of this byte array output stream to
     * the specified output stream argument, as if by calling the output
     * stream's write method using <code>out.write(buf, 0, count)</code>.
     *
     * @param      out   the output stream to which to write the data.
     * @exception  IOException  if an I/O error occurs.
     */
    //写到特定的输出流out中
    public synchronized void writeTo(OutputStream out) throws IOException {
        out.write(buf, 0, count);
    }

    /**
     * Resets the <code>count</code> field of this byte array output
     * stream to zero, so that all currently accumulated output in the
     * output stream is discarded. The output stream can be used again,
     * reusing the already allocated buffer space.
     *
     * @see     java.io.ByteArrayInputStream#count
     */
    //重置
    public synchronized void reset() {
        count = 0;
    }

    /**
     * Creates a newly allocated byte array. Its size is the current
     * size of this output stream and the valid contents of the buffer
     * have been copied into it.
     *
     * @return  the current contents of this output stream, as a byte array.
     * @see     java.io.ByteArrayOutputStream#size()
     */
    //生成字节数组
    public synchronized byte toByteArray()[] {
        return Arrays.copyOf(buf, count);
    }

    /**
     * Returns the current size of the buffer.
     *
     * @return  the value of the <code>count</code> field, which is the number
     *          of valid bytes in this output stream.
     * @see     java.io.ByteArrayOutputStream#count
     */
    //返回当前缓冲区大小
    public synchronized int size() {
        return count;
    }

    /**
     * Converts the buffer's contents into a string decoding bytes using the
     * platform's default character set. The length of the new <tt>String</tt>
     * is a function of the character set, and hence may not be equal to the
     * size of the buffer.
     *
     * <p> This method always replaces malformed-input and unmappable-character
     * sequences with the default replacement string for the platform's
     * default character set. The {@linkplain java.nio.charset.CharsetDecoder}
     * class should be used when more control over the decoding process is
     * required.
     *
     * @return String decoded from the buffer's contents.
     * @since  JDK1.1
     */
    //生成string
    public synchronized String toString() {
        return new String(buf, 0, count);
    }

    /**
     * Converts the buffer's contents into a string by decoding the bytes using
     * the named {@link java.nio.charset.Charset charset}. The length of the new
     * <tt>String</tt> is a function of the charset, and hence may not be equal
     * to the length of the byte array.
     *
     * <p> This method always replaces malformed-input and unmappable-character
     * sequences with this charset's default replacement string. The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param      charsetName  the name of a supported
     *             {@link java.nio.charset.Charset charset}
     * @return     String decoded from the buffer's contents.
     * @exception  UnsupportedEncodingException
     *             If the named charset is not supported
     * @since      JDK1.1
     */
    //生成特定的string
    public synchronized String toString(String charsetName)
        throws UnsupportedEncodingException
        {
            return new String(buf, 0, count, charsetName);
        }

    /**
     * Creates a newly allocated string. Its size is the current size of
     * the output stream and the valid contents of the buffer have been
     * copied into it. Each character <i>c</i> in the resulting string is
     * constructed from the corresponding element <i>b</i> in the byte
     * array such that:
     * <blockquote><pre>
     *     c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
     * </pre></blockquote>
     *
     * @deprecated This method does not properly convert bytes into characters.
     * As of JDK 1.1, the preferred way to do this is via the
     * <code>toString(String enc)</code> method, which takes an encoding-name
     * argument, or the <code>toString()</code> method, which uses the
     * platform's default character encoding.
     *
     * @param      hibyte    the high byte of each resulting Unicode character.
     * @return     the current contents of the output stream, as a string.
     * @see        java.io.ByteArrayOutputStream#size()
     * @see        java.io.ByteArrayOutputStream#toString(String)
     * @see        java.io.ByteArrayOutputStream#toString()
     */
    @Deprecated
    public synchronized String toString(int hibyte) {
         return new String(buf, hibyte, 0, count);
    }

    /**
     * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
     * this class can be called after the stream has been closed without
     * generating an <tt>IOException</tt>.
     */
    public void close() throws IOException {
    }

}

Java-IO之ByteArrayOutputStream的更多相关文章

  1. java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)

    前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会 ...

  2. 【java】内存流:java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream、java.io.CharArrayReader、java.io.CharArrayWriter

    package 内存流; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java. ...

  3. Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream

    类的继承关系 InputStream |__ ByteArrayInputStream OutputStream |__ ByteArrayOutputStream ByteArrayInputStr ...

  4. java io流 数据流 DataInputStream、DataOutputStream、ByteArrayInputStream、ByteArrayOutputStream

    例子程序: package io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ...

  5. Java IO 流-- 字节数组流ByteArrayInPutStream ByteArrayOutPutStream

    字节数组流输于缓冲流,放在jvm内存中,java可以直接操作.我们使用时可以不用关闭,交给GC垃圾回收机制处理. 当然我们为了保持良好习惯和代码一致性也可以加上关闭语句. 当其实我么打开ByteArr ...

  6. Java IO(七)ByteArrayInputStream 和 ByteArrayOutputStream

    Java IO(七)ByteArrayInputStream 和 ByteArrayOutputStream 一.介绍 ByteArrayInputStream 和 ByteArrayOutputSt ...

  7. Java IO之字符流和文件

    前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...

  8. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  9. Java IO流学习总结

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  10. [Java IO]02_字节流

    概要 字节流有两个核心抽象类:InputStream 和 OutputStream.所有的字节流类都继承自这两个抽象类. InputStream 负责输入,OutputStream 负责输出. 字节流 ...

随机推荐

  1. RESTful 最佳实战

    在GitHub上看到一本不错的关于REST实战的书,很高兴分享阅读笔记.[下载地址] 一.什么是REST(WHAT) REST架构描述了六种约束.(统一接口.无状态.可缓存.CS架构.分层系统.按需编 ...

  2. SpringMVC中HandlerMapping的三种配置方式

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-/ ...

  3. getBoundingClientRect方法获取元素在页面中的相对位置

    获取元素位置可以用 offset 或 getBoundingClientRect,使用 offset 因为兼容性不好,比较麻烦,offset获取位置会形成"回溯".而 getBou ...

  4. c# datatable row

    在指定索引位置插入新行 string fzmc = rs["fzmc"].ToString(); string mkmc = rs["mkmc"].ToStri ...

  5. rhel7 配置普通用户使用sudo

    rhel服务器版本安装之后,默认创建的用户不能使用sudo.使用sudo,会提示 user1 is not in the sudoers file. This incident will be rep ...

  6. HTML DOM 改变 HTML 内容

    HTML DOM 允许 JavaScript 改变 HTML 元素的内容. 改变 HTML 输出流 JavaScript 能够创建动态的 HTML 内容: 今天的日期是: Thu Feb 25 201 ...

  7. Python3 循环

    Python中的循环语句有 for 和 while. Python循环语句的控制结构图如下所示: while 循环 Python中while语句的一般形式: while 判断条件: statement ...

  8. Java内存泄漏分析系列之三:jstat命令的使用及VM Thread分析

    原文地址:http://www.javatang.com 使用jstat命令 当服务器CPU100%的时候,通过定位占用资源最大的线程定位到 VM Thread: "VM Thread&qu ...

  9. Bash shell中的位置参数$#,$*,$@,$0,$1,$2...及特殊参数$?,$-等的含义

    http://hi.baidu.com/lolorosa/blog/item/5775a608bd670d33b0351da7.html $# 是传给脚本的参数个数 $@ 是传给脚本的所有参数的列表 ...

  10. dynamic initializer和全局变量

    "慎用全局变量,包括全局静态变量" 是众所周知的原则,因为全局变量除了会增加程序的维护成本. 如果全局变量是个复杂的对象,并且还使用其他的全局变量,那情况就变得复杂的多.因为全局变 ...