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

本文深入介绍了ByteArrayOutputStream的概念及其在Java中的应用。探讨了其构造方法、关键函数如write、toByteArray等,并通过示例代码展示了如何操作字节数据。


前面学习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\n", 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\n", baos);
44 
45         // 计算长度
46         int size = baos.size();
47         System.out.printf("size=%s\n", size);
48 
49         // 转换成byte[]数组
50         byte[] buf = baos.toByteArray();
51         String str = new String(buf);
52         System.out.printf("str=%s\n", str);
53 
54         // 将baos写入到另一个输出流中
55         try {
56             ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
57             baos.writeTo((OutputStream)baos2);
58             System.out.printf("baos2=%s\n", 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)

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值