ByteArrayOutputStream简介和使用_动力节点Java学院整理

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) 

package java.io;
 public abstract class OutputStream implements Closeable, Flushable {
   // 将字节b写入到“输出流”中。
   // 它在子类中实现!
   public abstract void write(int b) throws IOException;
   // 写入字节数组b到“字节数组输出流”中。
   public void write(byte b[]) throws IOException {
    write(b, 0, b.length);
   }
   // 写入字节数组b到“字节数组输出流”中,并且off是“数组b的起始位置”,len是写入的长度
   public void write(byte b[], int off, int len) throws IOException {
     if (b == null) {
       throw new NullPointerException();
    } else if ((off < 0) || (off > b.length) || (len < 0) ||
          ((off + len) > b.length) || ((off + len) < 0)) {
      throw new IndexOutOfBoundsException();
     } else if (len == 0) {
      return;
     }
     for (int i = 0 ; i < len ; i++) {
      write(b[off + i]);
     }
   }
   public void flush() throws IOException {
   }
   public void close() throws IOException {
   }
 }

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

 package java.io;
  import java.util.Arrays;
  public class ByteArrayOutputStream extends OutputStream {
    // 保存“字节数组输出流”数据的数组
    protected byte buf[];
   // “字节数组输出流”的计数
   protected int count;
   // 构造函数:默认创建的字节数组大小是。
   public ByteArrayOutputStream() {
     this(32);
   }
   // 构造函数:创建指定数组大小的“字节数组输出流”
   public ByteArrayOutputStream(int size) {
     if (size < 0) {
       throw new IllegalArgumentException("Negative initial size: "
                         + size);
     }
     buf = new byte[size];
   }
   // 确认“容量”。
   // 若“实际容量 < minCapacity”,则增加“字节数组输出流”的容量
   private void ensureCapacity(int minCapacity) {
     // overflow-conscious code
     if (minCapacity - buf.length > 0)
       grow(minCapacity);
   }
   // 增加“容量”。
   private void grow(int minCapacity) {
     int oldCapacity = buf.length;
     // “新容量”的初始化 = “旧容量”x2
     int newCapacity = oldCapacity << 1;
     // 比较“新容量”和“minCapacity”的大小,并选取其中较大的数为“新的容量”。
     if (newCapacity - minCapacity < 0)
      newCapacity = minCapacity;
     if (newCapacity < 0) {
       if (minCapacity < 0) // overflow
         throw new OutOfMemoryError();
       newCapacity = Integer.MAX_VALUE;
     }
     buf = Arrays.copyOf(buf, newCapacity);
   }
   // 写入一个字节b到“字节数组输出流”中,并将计数+1
  public synchronized void write(int b) {
     ensureCapacity(count + 1);
     buf[count] = (byte) b;
     count += 1;
   }
   // 写入字节数组b到“字节数组输出流”中。off是“写入字节数组b的起始位置”,len是写入的长度
   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;
   }
   // 写入输出流outb到“字节数组输出流”中。
   public synchronized void writeTo(OutputStream out) throws IOException {
     out.write(buf, 0, count);
   }
   // 重置“字节数组输出流”的计数。
   public synchronized void reset() {
     count = 0;
   }
   // 将“字节数组输出流”转换成字节数组。
   public synchronized byte toByteArray()[] {
     return Arrays.copyOf(buf, count);
   }
   // 返回“字节数组输出流”当前计数值
   public synchronized int size() {
     return count;
   }
   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);
   }
   @Deprecated
   public synchronized String toString(int hibyte) {
    return new String(buf, hibyte, 0, count);
   }
   public void close() throws IOException {
   }
 }

说明:

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):

 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
 /**
  * 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

以上所述是小编给大家介绍的ByteArrayOutputStream简介和使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重复读取配置文件的方法

    ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据.在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去.具体用法如下: ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组. ByteA

  • ByteArrayInputStream简介和使用_动力节点Java学院整理

    ByteArrayInputStream 介绍 ByteArrayInputStream 是字节数组输入流.它继承于InputStream. 它包含一个内部缓冲区,该缓冲区包含从流中读取的字节:通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的. 我们都知道,InputStream通过read()向外提供接口,供它们来读取字节数据:而ByteArrayInputStream 的内部额外的定义了一个计数器,它被用来跟踪 read() 方

  • ByteArrayOutputStream简介和使用_动力节点Java学院整理

    ByteArrayOutputStream 介绍 ByteArrayOutputStream 是字节数组输出流.它继承于OutputStream. ByteArrayOutputStream 中的数据被写入一个 byte 数组.缓冲区会随着数据的不断写入而自动增长.可使用 toByteArray() 和 toString() 获取数据. OutputStream 函数列表 我们来看看ByteArrayOutputStream的父类OutputStream的函数接口. // 构造函数 Output

  • Java异常简介和架构_动力节点Java学院整理

    Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机制. Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性.在有效使用异常的情况下,异常能清晰的回答what, where, why这3个问题:异常类型回答了"什么"被抛出,异常堆栈跟踪回答了"在哪"抛出,异常信息回答了"为什么"会抛出. Java异常机制用到的几个关键字:try.catch.finally.throw.thro

  • Struts1简介和入门_动力节点Java学院整理

    本文为大家分享了Struts1简介和入门的学习资料,供大家参考,具体内容如下 1. 框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法.也就是说框架是一个半成品的应用程序. 我们所面对的应用程序一般都是分为两部分,一部分是业务相关的组件部分,另一部分是和业务无关的组件部分.而我们知道和业务相关的组件部分的重用性是非常低的,这也是显而易见的事情:而和业务无关的组件部分,如验证.异常.程序流程控制等等服务组件的复用性是非常高的.所以当人们在不同的应

  • mybatis简介与配置_动力节点Java学院整理

    MyBatis简介 MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架.MyBatis 摒除了大部分的JDBC代码.手工设置参数和结果集重获.MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型.Map 接口和POJO 到数据库记录.相对Hibernate和Apache OJB等"一站式"ORM解决方案而言,Mybatis 是一种"半自动化"的ORM实现. 需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包

  • Nginx简介_动力节点Java学院整理

    1.什么是Nginx Nginx来自俄罗斯的Igor Sysoev在为Rambler Media(http://www.rambler.ru/)工作期间,使用C语言开发了Nginx.Nginx作为Web服务器,一直为俄罗斯著名的门户网站Rambler Media提供着出色.稳定的服务. Igor Sysoev将Nginx的代码开源,并且赋予其最自由的2-clause BSD-like license许可证.由于Nginx使用基于事件驱动的架构能够并发处理百万级别的TCP连接,高度模块化的设计和自

  • Java Map简介_动力节点Java学院整理

    Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口. Map 接口提供三种collection 视图,允许以键集.值集或键-值映射关系集的形式查看某个映射的内容.映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺序.某些映射实现可明确保证其顺序,如 TreeMap 类:另一些映射实现则不保证顺序,如HashMap 类. 注:将可变对象用作映射键时必须格外小心.当对

  • Java中Object toString方法简介_动力节点Java学院整理

    一.Object类介绍  Object类在Java里面是一个比较特殊的类,JAVA只支持单继承,子类只能从一个父类来继承,如果父类又是从另外一个父类继承过来,那他也只能有一个父类,父类再有父类,那也只能有一个,JAVA为了组织这个类组织得比较方便,它提供了一个最根上的类,相当于所有的类都是从这个类继承,这个类就叫Object.所以Object类是所有JAVA类的根基类,是所有JAVA类的老祖宗.所有的类,不管是谁,都是从它继承下来的. 二.toString方法介绍  一个字符串和另外一种类型连接

  • Java Set简介_动力节点Java学院整理

    1. 概述   Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品种类的存储需求.Set 可以被用来过滤在其他集合中存放的元素,从而得到一个没有包含重复新的集合. 2. 常用方法 按照定义,Set 接口继承 Collection 接口,而且它不允许集合中存在重复项.所有原始方法都是现成的,没有引入新方法.具体的 Set 实现类依赖添加的对象的 equals()

  • RandomAccessFile简介_动力节点Java学院整理

    RandomAccessFile RandomAccessFile 是随机访问文件(包括读/写)的类.它支持对文件随机访问的读取和写入,即我们可以从指定的位置读取/写入文件数据. 需要注意的是,RandomAccessFile 虽然属于java.io包,但它不是InputStream或者OutputStream的子类:它也不同于FileInputStream和FileOutputStream. FileInputStream 只能对文件进行读操作,而FileOutputStream 只能对文件进

随机推荐