`

源码剖析之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实现远程屏幕监视

    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)** 为了提高...

    java 读取excel内容 创建excel 插入文字及图片

    import java.io.FileInputStream; import java.io.IOException; public class ExcelReader { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream(new File...

Global site tag (gtag.js) - Google Analytics