`

源码剖析之java.io.ByteArrayInputStream

阅读更多
java的数据源有很多,比如:文件、网络、管道、命令行,甚至是内存。
其实我个人认为 java对流的源头概念做了更抽象的扩展,让一些本来很直观的操作,也封装为io流的形式,会增加理解的坡度。

比如: java.io.ByteArrayInputStream 其实完全可以不设计为流的一部分,因为其本质不过是对byte[] 的一个数据读取的处理,即使不用流的概念,完全可以自己实现自己想要的功能。 但是在某些情况下,使用这种流可能和其他的流更好统一交互。所以从这一点看还是有点意义的

下面就分析java.io.ByteArrayInputStream 的源码实现,因为完全是对byte[]的处理,所以很简单。

另外:数组是java数据结构中常用的底层数据结构。字节流的操作很大程度上是byte[]字节数组的操作 或复制 或移动 或扩展


package java.io;

/**
 其内部是通过保持一个byte[] 来实现的
 */
public
class ByteArrayInputStream extends InputStream {

        protected byte buf[];

   /**
    * --标志从inputStream读取的下一个字符的索引
     * --pos 不能为负值
     *--pos 必须不大于 count
    * --read方法读取的下一个byte是 buf[pos]
    */
    protected int pos;

    /**
     *-- 当前在stream中 标记的位置
     *--初始化时 ByteArrayInputStream 被标记为0
     *-- mark(int)方法可以设定mark的值
      */
    protected int mark = 0;

 
    protected int count;

    /**
     * 构造方法需要传递 byte[]数组
     */
    public ByteArrayInputStream(byte buf[]) {
	this.buf = buf;
        this.pos = 0; //当前位置设置为0
	this.count = buf.length; //count 设置为buf.length
    }

    /**
     *同上,只是buf 的数组事从offset开始算的
     */
    public ByteArrayInputStream(byte buf[], int offset, int length) {
	this.buf = buf;
        this.pos = offset;
	this.count = Math.min(offset + length, buf.length);
        this.mark = offset;
    }

    /**
     * 读下一个字节。可以看到此字节就是buf[pos++]
     */
    public synchronized int read() {
	return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

    /**
     * 其覆盖了父类的方法,父类是循环调用read方法
      其实read方法就是 buf数组内容 copy 到 b中。
     */
    public synchronized int read(byte b[], int off, int len) {
	if (b == null) {
	    throw new NullPointerException();
	} else if (off < 0 || len < 0 || len > b.length - off) {
	    throw new IndexOutOfBoundsException();
	}
	if (pos >= count) {
	    return -1;
	}
	if (pos + len > count) {
	    len = count - pos;
	}
	if (len <= 0) {
	    return 0;
	}
	System.arraycopy(buf, pos, b, off, len); //其实就是数组的复制操作,java对很多底层的操作归根结底,大部分都是对数组的操作。
	pos += len;
	return len;
    }

    /**
     * 跳过n字节,其实就是对pos的处理,标志当前应该读的下一个字符
     */
    public synchronized long skip(long n) {
	if (pos + n > count) {
	    n = count - pos;
	}
	if (n < 0) {
	    return 0;
	}
	pos += n;
	return n;
    }

    /**
     *还剩下多少可以读的自己
     */
    public synchronized int available() {
	return count - pos;
    }

    
    public boolean markSupported() {
	return true;
    }

    /**
     * 可设置标记
     */
    public void mark(int readAheadLimit) {
	mark = pos;
    }

    /**
     *重置后讲从最初的位置开始读
     */
    public synchronized void reset() {
	pos = mark;
    }

    /**
     *ByteArrayInputStream 的close 方法无效
     */
    public void close() throws IOException {
    }

}

1
1
分享到:
评论

相关推荐

    java.io.Reader 和 java.io.InputStream 的区别

    ### Java.io.Reader与Java.io.InputStream的关键差异解析 在深入探讨`java.io.Reader`与`java.io.InputStream`的具体差异之前,我们首先需要理解这两者在Java I/O操作中的基础角色。`java.io.Reader`和`java.io....

    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.io详解

    ### Java IO流详解 #### 一、Java IO流概述 Java IO流是Java标准库中的一个重要组成部分,主要用于处理数据的输入输出操作。根据处理的数据类型不同,Java IO流被分为两大类:字节流(byte streams)和字符流...

    java jdk io包类详解

    ### Java JDK IO包类详解 #### 概述 Java平台提供的`io`包为开发者提供了访问文件系统、对象序列化等功能...总之,`java.io`包是Java编程语言的重要组成部分,对于任何想要深入理解Java平台的开发者来说都至关重要。

    java_IO.rar

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

    最最常用的 100 个 Java类分享

    37. `java.io.ByteArrayInputStream`:ByteArrayInputStream从字节数组中读取数据。 38. `java.io.PrintWriter`:PrintWriter用于向文本流写入打印数据。 39. `java.util.Calendar`:Calendar是抽象基类,用于日期...

    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 ...

    java jsp IO包 教程 新手入门

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

    java IO 类层次图

    ### Java IO 类层次结构解析 #### 一、概述 Java IO(Input/Output)系统是Java平台中的一个重要组成部分,用于处理程序与外部设备之间的数据交换。Java IO系统提供了丰富的类来支持不同类型的输入输出操作,包括...

    【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实现图片和Base64之间的相互转化

    import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.nio.file.Files; import javax.imageio.ImageIO; import java.util.Base64; public class Base64ToImage { ...

    Java_IO完全总结

    Java IO系统主要包括两个包:`java.io`和`java.nio`(New IO),其中`java.io`提供了一系列基于流的I/O操作接口与实现类,而`java.nio`则提供了更高效的数据访问方式,如通道和缓冲区等。 Java IO系统的设计原则之...

    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_IO流的处理.ppt

    **Java.io包中的InputStream子类** - FileInputStream:用于从文件读取字节。 - ByteArrayInputStream:从内存中的字节数组读取数据。 - FilterInputStream:抽象类,作为过滤流的基类,用于添加额外功能。 - ...

    Java IO

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

Global site tag (gtag.js) - Google Analytics