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. 查询优化--ORDER BY查询优化

    Mysql 系列文章主页 =============== ORDER BY 子句,尽量使用 Index 查询,避免使用 FileSort 排序 尽可能在索引列上完成排序操作,遵照索引的最佳左前缀原则 ...

  2. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】

    Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...

  3. Python安装与环境变量

    Python安装与环境变量的配置  python下载: Python安装包下载地址:http://www.python.org/ 根据实际的操作系统,安装合适的安装版本.    Python安装: 本 ...

  4. Python之禅及其翻译

    凡是用过 Python的人,基本上都知道在交互式解释器中输入 import this 就会显示 Tim Peters 的 The Zen of Python,但它那偈语般的语句有点令人费解,所以我想分 ...

  5. java里String类为何被设计为final

    前些天面试遇到一个非常难的关于String的问题,"String为何被设计为不可变的"?类似的问题也有"String为何被设计为final?"个人认为还是前面一 ...

  6. JAVA Eclipse使用Maven构建web项目详解(SSM框架)

    tips: 启动项目后,welcome-file的链接即为测试用例 部署maven web项目 Eclipse使用Maven构建web项目详解 pom.xml添加webapp依赖: <depen ...

  7. ubuntu16.04下安装opencv

    source url:http://blog.csdn.net/zhuiqiuk/article/details/5308505811 1 依赖包sudo apt-get install build- ...

  8. Lucene 查询(Query)子类

    QueryParser(单域查询) QueryParser子类对单个域查询时创建查询query,构造方法中需要传入Lucene版本号,检索域名和分词器. QueryParser parser = ne ...

  9. Android简易实战教程--第三十六话《电话录音》

    今天完成一个简单的电话录音功能,即接通电话后,立即录下自己打电话的声音.实现起来比较简单:一个服务,一个TelephonyManager.一个MediaRecorder就够了. 1.布局提供一个开启录 ...

  10. 【Unity Shader】新书封面 — Low Polygon风格的渲染

    写在前面 最近又开心又担心,因为我的书马上就要上市了,开心当然是因为等了这么久终于可以如愿了,担心是因为不少人对它的期待都很大,我第一次写书,能力也有限,不知道能不能让大家满意,让大家也都喜欢上它.不 ...