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



    前面学习ByteArrayInputStream,了解了“输入流”。接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream。
    本章,我们会先对ByteArrayOutputStream进行介绍,在了解了它的源码之后,再通过示例来掌握如何使用它。

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_03.html

    ByteArrayOutputStream 介绍

    ByteArrayOutputStream 是字节数组输出流。它继承于OutputStream。
    ByteArrayOutputStream 中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。


    OutputStream 函数列表

    我们来看看ByteArrayOutputStream的父类OutputStream的函数接口

    // 构造函数
    OutputStream()
    
             void    close()
             void    flush()
             void    write(byte[] buffer, int offset, int count)
             void    write(byte[] buffer)
    abstract void    write(int oneByte)

    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)

    OutputStream和ByteArrayOutputStream源码分析

    OutputStream是ByteArrayOutputStream的父类,我们先看看OutputStream的源码,然后再学ByteArrayOutputStream的源码。

    1. OutputStream.java源码分析(基于jdk1.7.40)

     1 package java.io;
     2 
     3 public abstract class OutputStream implements Closeable, Flushable {
     4     // 将字节b写入到“输出流”中。
     5     // 它在子类中实现!
     6     public abstract void write(int b) throws IOException;
     7 
     8     // 写入字节数组b到“字节数组输出流”中。
     9     public void write(byte b[]) throws IOException {
    10         write(b, 0, b.length);
    11     }
    12 
    13     // 写入字节数组b到“字节数组输出流”中,并且off是“数组b的起始位置”,len是写入的长度
    14     public void write(byte b[], int off, int len) throws IOException {
    15         if (b == null) {
    16             throw new NullPointerException();
    17         } else if ((off < 0) || (off > b.length) || (len < 0) ||
    18                    ((off + len) > b.length) || ((off + len) < 0)) {
    19             throw new IndexOutOfBoundsException();
    20         } else if (len == 0) {
    21             return;
    22         }
    23         for (int i = 0 ; i < len ; i++) {
    24             write(b[off + i]);
    25         }
    26     }
    27 
    28     public void flush() throws IOException {
    29     }
    30 
    31     public void close() throws IOException {
    32     }
    33 }
    View Code

    2. ByteArrayOutputStream 源码分析(基于jdk1.7.40)

      1 package java.io;
      2 
      3 import java.util.Arrays;
      4 
      5 public class ByteArrayOutputStream extends OutputStream {
      6 
      7     // 保存“字节数组输出流”数据的数组
      8     protected byte buf[];
      9 
     10     // “字节数组输出流”的计数
     11     protected int count;
     12 
     13     // 构造函数:默认创建的字节数组大小是32。
     14     public ByteArrayOutputStream() {
     15         this(32);
     16     }
     17 
     18     // 构造函数:创建指定数组大小的“字节数组输出流”
     19     public ByteArrayOutputStream(int size) {
     20         if (size < 0) {
     21             throw new IllegalArgumentException("Negative initial size: "
     22                                                + size);
     23         }
     24         buf = new byte[size];
     25     }
     26 
     27     // 确认“容量”。
     28     // 若“实际容量 < minCapacity”,则增加“字节数组输出流”的容量
     29     private void ensureCapacity(int minCapacity) {
     30         // overflow-conscious code
     31         if (minCapacity - buf.length > 0)
     32             grow(minCapacity);
     33     }
     34 
     35     // 增加“容量”。
     36     private void grow(int minCapacity) {
     37         int oldCapacity = buf.length;
     38         // “新容量”的初始化 = “旧容量”x2
     39         int newCapacity = oldCapacity << 1;
     40         // 比较“新容量”和“minCapacity”的大小,并选取其中较大的数为“新的容量”。
     41         if (newCapacity - minCapacity < 0)
     42             newCapacity = minCapacity;
     43         if (newCapacity < 0) {
     44             if (minCapacity < 0) // overflow
     45                 throw new OutOfMemoryError();
     46             newCapacity = Integer.MAX_VALUE;
     47         }
     48         buf = Arrays.copyOf(buf, newCapacity);
     49     }
     50 
     51     // 写入一个字节b到“字节数组输出流”中,并将计数+1
     52     public synchronized void write(int b) {
     53         ensureCapacity(count + 1);
     54         buf[count] = (byte) b;
     55         count += 1;
     56     }
     57 
     58     // 写入字节数组b到“字节数组输出流”中。off是“写入字节数组b的起始位置”,len是写入的长度
     59     public synchronized void write(byte b[], int off, int len) {
     60         if ((off < 0) || (off > b.length) || (len < 0) ||
     61             ((off + len) - b.length > 0)) {
     62             throw new IndexOutOfBoundsException();
     63         }
     64         ensureCapacity(count + len);
     65         System.arraycopy(b, off, buf, count, len);
     66         count += len;
     67     }
     68 
     69     // 写入输出流outb到“字节数组输出流”中。
     70     public synchronized void writeTo(OutputStream out) throws IOException {
     71         out.write(buf, 0, count);
     72     }
     73 
     74     // 重置“字节数组输出流”的计数。
     75     public synchronized void reset() {
     76         count = 0;
     77     }
     78 
     79     // 将“字节数组输出流”转换成字节数组。
     80     public synchronized byte toByteArray()[] {
     81         return Arrays.copyOf(buf, count);
     82     }
     83 
     84     // 返回“字节数组输出流”当前计数值
     85     public synchronized int size() {
     86         return count;
     87     }
     88 
     89     public synchronized String toString() {
     90         return new String(buf, 0, count);
     91     }
     92 
     93     public synchronized String toString(String charsetName)
     94         throws UnsupportedEncodingException
     95     {
     96         return new String(buf, 0, count, charsetName);
     97     }
     98 
     99     @Deprecated
    100     public synchronized String toString(int hibyte) {
    101         return new String(buf, hibyte, 0, count);
    102     }
    103 
    104     public void close() throws IOException {
    105     }
    106 }
    View Code

    说明
    ByteArrayOutputStream实际上是将字节数据写入到“字节数组”中去。
    (01) 通过ByteArrayOutputStream()创建的“字节数组输出流”对应的字节数组大小是32。
    (02) 通过ByteArrayOutputStream(int size) 创建“字节数组输出流”,它对应的字节数组大小是size。
    (03) write(int oneByte)的作用将int类型的oneByte换成byte类型,然后写入到输出流中。
    (04) write(byte[] buffer, int offset, int len) 是将字节数组buffer写入到输出流中,offset是从buffer中读取数据的起始偏移位置,len是读取的长度。
    (05) writeTo(OutputStream out) 将该“字节数组输出流”的数据全部写入到“输出流out”中。

    示例代码

    关于ByteArrayOutputStream中API的详细用法,参考示例代码(ByteArrayOutputStreamTest.java):

     1 import java.io.IOException;
     2 import java.io.OutputStream;
     3 import java.io.ByteArrayOutputStream;
     4 import java.io.ByteArrayInputStream;
     5 
     6 /**
     7  * ByteArrayOutputStream 测试程序
     8  *
     9  * @author skywang
    10  */
    11 public class ByteArrayOutputStreamTest {
    12 
    13     private static final int LEN = 5;
    14     // 对应英文字母“abcddefghijklmnopqrsttuvwxyz”
    15     private static final byte[] ArrayLetters = {
    16         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
    17         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
    18     };
    19 
    20     public static void main(String[] args) {
    21         //String tmp = new String(ArrayLetters);
    22         //System.out.println("ArrayLetters="+tmp);
    23 
    24         tesByteArrayOutputStream() ;
    25     }
    26 
    27     /**
    28      * ByteArrayOutputStream的API测试函数
    29      */
    30     private static void tesByteArrayOutputStream() {
    31         // 创建ByteArrayOutputStream字节流
    32         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    33 
    34         // 依次写入“A”、“B”、“C”三个字母。0x41对应A,0x42对应B,0x43对应C。
    35         baos.write(0x41);
    36         baos.write(0x42);
    37         baos.write(0x43);
    38         System.out.printf("baos=%s
    ", baos);
    39 
    40         // 将ArrayLetters数组中从“3”开始的后5个字节写入到baos中。
    41         // 即对应写入“0x64, 0x65, 0x66, 0x67, 0x68”,即“defgh”
    42         baos.write(ArrayLetters, 3, 5);
    43         System.out.printf("baos=%s
    ", baos);
    44 
    45         // 计算长度
    46         int size = baos.size();
    47         System.out.printf("size=%s
    ", size);
    48 
    49         // 转换成byte[]数组
    50         byte[] buf = baos.toByteArray();
    51         String str = new String(buf);
    52         System.out.printf("str=%s
    ", str);
    53 
    54         // 将baos写入到另一个输出流中
    55         try {
    56             ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
    57             baos.writeTo((OutputStream)baos2);
    58             System.out.printf("baos2=%s
    ", baos2);
    59         } catch (IOException e) {
    60             e.printStackTrace();
    61         }
    62     }
    63 }

    运行结果
    baos=ABC
    baos=ABCdefgh
    size=8
    str=ABCdefgh
    baos2=ABCdefgh


    更多内容

    1. java 集合系列目录(Category)

    2. java io系列01之 IO框架

    3. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

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

  • 相关阅读:
    查看端口有没有被占用
    微信公众号2()
    How to insert a segment of noise to music file
    puppet practice
    Docker Commands
    LempelZiv algorithm realization
    The algorithm of entropy realization
    Java network programmingguessing game
    Deploy Openstack with RDO and Change VNC console to Spice
    puppet overview
  • 原文地址:https://www.cnblogs.com/skywang12345/p/io_03.html
Copyright © 2020-2023  润新知