我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕。
本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法。
转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_02.html
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)
1 package java.io;
2
3 public abstract class InputStream implements Closeable {
4
5 // 能skip的大小
6 private static final int MAX_SKIP_BUFFER_SIZE = 2048;
7
8 // 从输入流中读取数据的下一个字节。
9 public abstract int read() throws IOException;
10
11 // 将数据从输入流读入 byte 数组。
12 public int read(byte b[]) throws IOException {
13 return read(b, 0, b.length);
14 }
15
16 // 将最多 len 个数据字节从此输入流读入 byte 数组。
17 public int read(byte b[], int off, int len) throws IOException {
18 if (b == null) {
19 throw new NullPointerException();
20 } else if (off < 0 || len < 0 || len > b.length - off) {
21 throw new IndexOutOfBoundsException();
22 } else if (len == 0) {
23 return 0;
24 }
25
26 int c = read();
27 if (c == -1) {
28 return -1;
29 }
30 b[off] = (byte)c;
31
32 int i = 1;
33 try {
34 for (; i < len ; i++) {
35 c = read();
36 if (c == -1) {
37 break;
38 }
39 b[off + i] = (byte)c;
40 }
41 } catch (IOException ee) {
42 }
43 return i;
44 }
45
46 // 跳过输入流中的n个字节
47 public long skip(long n) throws IOException {
48
49 long remaining = n;
50 int nr;
51
52 if (n <= 0) {
53 return 0;
54 }
55
56 int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
57 byte[] skipBuffer = new byte[size];
58 while (remaining > 0) {
59 nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
60 if (nr < 0) {
61 break;
62 }
63 remaining -= nr;
64 }
65
66 return n - remaining;
67 }
68
69 public int available() throws IOException {
70 return 0;
71 }
72
73 public void close() throws IOException {}
74
75 public synchronized void mark(int readlimit) {}
76
77 public synchronized void reset() throws IOException {
78 throw new IOException("mark/reset not supported");
79 }
80
81 public boolean markSupported() {
82 return false;
83 }
84 }