ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕。
本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法。
ByteArrayInputStream 介绍
ByteArrayInputStream 是字节数组输入流。它继承于InputStream。
它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的。
我们都知道,InputStream通过read()向外提供接口,供它们来读取字节数据;而ByteArrayInputStream 的内部额外的定义了一个计数器,它被用来跟踪 read() 方法要读取的下一个字节。
InputStream 函数列表
// 构造函数 InputStream() int available() void close() void mark(int readlimit) boolean markSupported() int read(byte[] buffer) abstract int read() int read(byte[] buffer, int offset, int length) synchronized void reset() long skip(long byteCount)
ByteArrayInputStream 函数列表
// 构造函数 ByteArrayInputStream(byte[] buf) ByteArrayInputStream(byte[] buf, int offset, int length) synchronized int available() void close() synchronized void mark(int readlimit) boolean markSupported() synchronized int read() synchronized int read(byte[] buffer, int offset, int length) synchronized void reset() synchronized long skip(long byteCount)
InputStream和ByteArrayInputStream源码分析
InputStream是ByteArrayInputStream的父类,我们先看看InputStream的源码,然后再学ByteArrayInputStream的源码。
1. InputStream.java源码分析(基于jdk1.7.40)
package java.io; public abstract class InputStream implements Closeable { // 能skip的大小 private static final int MAX_SKIP_BUFFER_SIZE = 2048; // 从输入流中读取数据的下一个字节。 public abstract int read() throws IOException; // 将数据从输入流读入 byte 数组。 public int read(byte b[]) throws IOException { return read(b, 0, b.length); } // 将最多 len 个数据字节从此输入流读入 byte 数组。 public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; } // 跳过输入流中的n个字节 public long skip(long n) throws IOException { long remaining = n; int nr; if (n <= 0) { return 0; } int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); byte[] skipBuffer = new byte[size]; while (remaining > 0) { nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); if (nr < 0) { break; } remaining -= nr; } return n - remaining; } public int available() throws IOException { return 0; } public void close() throws IOException {} public synchronized void mark(int readlimit) {} public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } public boolean markSupported() { return false; } }