`

源码剖析之java.io.ByteArrayOutputStream

阅读更多
对应于 java.io.ByteArrayInputStream 的byte内存输入流,jdk同样提供了java.io. ByteArrayOutputStream byte[]输出流的概念。
功能很简单,就是通过write方法 把字节写入到 byte[]中,取的时候直接toByteArray或者toString() 即可。

注意:此类是线程安全的。
实现方式:通过对方法 添加synchronized 关键字实现,另外Reader 顶层类则是通过Lock 锁,锁定当前流对象实现的。

功能分析如下:

package java.io;

import java.util.Arrays;

/**
 * This class implements an output stream in which the data is 
 * written into a byte array. The buffer automatically grows as data 
 * is written to it.   
   翻译:ByteArrayOutputStream 实现了OutputStream 接口,数据是写入到一个 byte[]里,并且buf 是自动增长的随着流的写入。
 * The data can be retrieved using <code>toByteArray()</code> and
 * <code>toString()</code>.  
   翻译:ByteArrayOutputStream 缓存的数据,可以通过 toByteArray 和 toString() 方法获取
 * <p>
 * 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>.  
 
   翻译:关闭ByteArrayOutputStream ,调用close方法是没有意义的。close是空实现,即便是关闭了也可以调用其他的方法。
 *
 * @author  Arthur van Hoff
 * @version %I%, %G%
 * @since   JDK1.0
 */

public class ByteArrayOutputStream extends OutputStream {

    /** 
     * 承载ByteArrayOutputStream 写入的数据
     */
    protected byte buf[];

    /**
     * buf 中当前有效的数据量 
     */
    protected int count;

    /**
     * 构造函数,默认创建的是一个长度为32的byte数组
     */
    public ByteArrayOutputStream() {
	     this(32);
    }

    /**
     * 同上
     */
    public ByteArrayOutputStream(int size) {
        if (size < 0) {
            throw new IllegalArgumentException("Negative initial size: "
                                               + size);
        }
	buf = new byte[size];
    }

    /**
     * 将b的低八位写入 buf数组里
     */
    public synchronized void write(int b) {
			int newcount = count + 1;
			if (newcount > buf.length) { //如果长度不够,那么将buf的长度扩展2倍。  另外:Arrays.copyOf  这个函数的含义请各位好好体会下,这个功能是数组操作最常用的功能!!
		            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
			}
			buf[count] = (byte)b;
			count = newcount; //每写入一个字节,count+1
    }

    /**
     * 将b 数组中的字节,从off开始 读取 len长度的byte数据。
       注意:父类可是循环写入的,这里进行覆盖一次性搞定。
     * @param   b     the data. 待写入的byte数组
     * @param   off   data 代写的开始位置
     * @param   len   写入的长度
     */
    public synchronized void write(byte b[], int off, int len) {
				if ((off < 0) || (off > b.length) || (len < 0) ||
			            ((off + len) > b.length) || ((off + len) < 0)) {
					    throw new IndexOutOfBoundsException();
					} else if (len == 0) {
					    return;
					}
        int newcount = count + len;
        if (newcount > buf.length) { //如果需要扩容
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
        }
        //否则直接copy即可
        System.arraycopy(b, off, buf, count, len); //System.arraycopy 也是操作数组最常用的功能。
        count = newcount;
    }

    /**
     * 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>.
     *
     以上方法都是写入byte 或者byte[] ,但是writeTo 责任直接把out流中的数据全部写入
     buf数组里。
     */
    public synchronized void writeTo(OutputStream out) throws IOException {
	out.write(buf, 0, count);
    }

    /**
     * 从新设置,count值改0
     */
    public synchronized void reset() {
	   count = 0;
    }

    /**
     返回流中的byte数组数据
     */
    public synchronized byte toByteArray()[] {
        return Arrays.copyOf(buf, count);
    }

    /**
     * 返回缓存中的数据长度
     *
     */
    public synchronized int size() {
	return count;
    }

    /**
     * 根据默认平台返回特定格式的string字符串
     */
    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);
    }


    /**
     * 无用的关闭
     *
     */
    public void close() throws IOException {
    }

}
分享到:
评论
2 楼 王新春 2016-08-02  
小侠有点帅哦 写道
此流怎么关闭新春

这个实现 可以不关闭的,哈哈,你居然也浏览博客
1 楼 小侠有点帅哦 2016-07-28  
此流怎么关闭新春

相关推荐

    java72-java-advance.rar

    a)java.sql b) java.util c) java.math d) java.io 2.不属于java.io包中的接口的一项是(C) a)DataInput b) DataOutput c) DataInputStream d) ObjectInput 3. ByteArrayOutputStream将下列哪一项作为输出流 C a)...

    java常用的工具类整理28个

    16. **java.io.ByteArrayInputStream**和**java.io.ByteArrayOutputStream**:用于内存中的字节流操作。 17. **java.util.zip.***:包括`ZipInputStream`、`ZipOutputStream`等,用于处理ZIP文件的压缩和解压。 18...

    java 中序列化NotSerializableException问题解决办法

    Java 中序列化 NotSerializableException 问题是 Java 开发中常见的问题之一。 NotSerializableException 是 Java 中的一个异常,它发生在尝试序列化一个不implement Serializable 接口的对象时。今天,我们将讨论 ...

    java_IO.rar

    Java IO(输入输出)是Java平台中的核心概念,主要用于数据的读取和写入操作。在Java SE中,IO框架提供了丰富的类库,使得开发者能够处理各种类型的数据流,包括文件、网络、内存等。本资源"java_IO.rar"包含了关于...

    java base64源码+jar包

    import java.io.*; public class Base64Example { public static void main(String[] args) throws IOException { // 编码 byte[] data = "Hello, World!".getBytes("UTF-8"); ByteArrayOutputStream ...

    最最常用的 100 个 Java类分享

    30. `java.io.ByteArrayOutputStream`:ByteArrayOutputStream将数据写入字节数组。 31. `java.util.regex.Matcher`:Matcher类用于执行匹配操作,与Pattern配合使用。 32. `android.os.Bundle`:Android中的...

    java jsp IO包 教程 新手入门

    Java通过`java.io`包提供了一系列强大的API来支持各种I/O操作。本文旨在为新手提供一个全面的Java I/O教程,帮助读者理解Java I/O的基本概念、架构以及如何使用这些API。 #### 二、Java I/O概述 Java中的I/O系统...

    【IT十八掌徐培成】Java基础第16天-04.ByteArrayInputStream-ByteArrayOutputStream.zip

    今天我们要深入学习的是Java中的两个重要类:ByteArrayInputStream和ByteArrayOutputStream,它们属于Java.io包,是处理内存中字节数组的流对象。 ByteArrayInputStream是InputStream的一个子类,它允许我们从字节...

    common.io详细说明

    根据提供的信息,我们可以深入探讨`common.io`相关的知识点,这里主要聚焦于Java IO系统的核心概念、流类别及其应用。下面将详细阐述标题和描述中提到的知识点。 ### Java IO系统概述 Java IO(输入/输出)系统是...

    一文读懂Java IO流 1. IO流基础概念 1.1 什么是IO流 1.2 IO流的分类 1.2.1 按数据传输单位分类 1.2.2 按功能角色分类 1.3 Java IO流体系结构 1.4 流的基

    一文读懂Java IO流 1. IO流基础概念 1.1 什么是IO流 1.2 IO流的分类 1.2.1 按数据传输单位分类 1.2.2 按功能角色分类 1.3 Java IO流体系结构 1.4 流的基本操作 2. 字节流 2.1 InputStream - 输入字节流 2.2 ...

    Java实现远程屏幕监视

    import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import ...

    java_io详解

    在Java中,IO操作主要通过`java.io`包来实现,这个包包含了用于文件读写、标准设备输出等操作的一系列类和接口。Java IO的主要特点是基于流的概念来进行数据的输入和输出。 #### 2. Java IO模型 Java的IO模型采用...

    JAVA程序设计:第14章 Java流式IO编程.ppt

    java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能。 Java流式IO编程的基本原理是:将不同的输入/输出源抽象表述为“流”,然后使用流类型(类或抽象类)来实现输入/输出功能。Java中有两种基本的流...

    Java 的 IO流笔记.md

    import java.io.FileInputStream; import java.io.IOException; public class ReadFileExample { public static void main(String[] args) { FileInputStream fis = null; try { // 创建字节输入流对象 fis = ...

    java生成二维码_java将二维码转换成base64

    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Base64; public class QRCodeToBase64 { public static void main(String[] args) throws ...

    Java IO

    Java IO的基本概念之一是流,它是一种数据传输的方式。Java中的流被抽象成一系列连续的数据元素,这些数据元素可以是字节或字符。流分为两种基本类型:输入流和输出流。输入流是从外部源读取数据到程序,而输出流则...

    Io框架与类图

    在IT领域,输入/输出(Input/Output,简称IO)框架是处理数据传输的核心部分,尤其是在Java编程语言中。本文将深入探讨IO框架,并通过类图解析其内部结构和主要组件,以帮助理解如何在实际应用中有效地使用IO流。 ...

    Java基于Base64实现编码解码图片文件

    首先,需要引入必要的jar包,包括java.awt.image.BufferedImage、java.io.ByteArrayOutputStream、java.io.File、java.io.FileOutputStream、java.net.MalformedURLException、java.net.URL、javax.imageio.ImageIO...

    Java二进制IO类与文件复制操作实例

    同样,字节输出流(OutputStream)的基类是`java.io.OutputStream`,子类有`FileOutputStream`(向文件写入字节)和`ByteArrayOutputStream`(向字节数组写入字节)。 3. **缓冲流(Buffered Streams)** 为了提高...

Global site tag (gtag.js) - Google Analytics