inputstream是一个抽象类,即表示所有字节输入流实现类的基类。它的作用就是抽象地表示所有从不同数据源产生输入的类,例如常见的fileinputstream、filterinputstream等。那些数据源呢?比如:
1) 字节数组(不代表string类,但可以转换) 2) string对象 3) 文件 4) 一个其他种类的流组成的序列化 (在分布式系统中常见) 5) 管道(多线程环境中的数据源) 等等
二者,注意它是属于字节流部分,而不是字符流(java.io中reader\writer,下面会讲到)。
源码如下:
<a href="http://www.bysocket.com/?p=585#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<code>/**</code>
<code> </code><code>* 所有字节输入流实现类的基类</code>
<code> </code><code>*/</code>
<code>public</code> <code>abstract</code> <code>class</code> <code>sinputstream {</code>
<code> </code><code>// 缓存区字节数组最大值</code>
<code> </code><code>private</code> <code>static</code> <code>final</code> <code>int</code> <code>max_skip_buffer_size =</code><code>2048</code><code>;</code>
<code> </code><code>// 从输入流中读取数据的下一个字节,以int返回</code>
<code> </code><code>public</code> <code>abstract</code> <code>int</code> <code>read()</code><code>throws</code> <code>ioexception;</code>
<code> </code><code>// 从输入流中读取数据的一定数量字节,并存储在缓存数组b</code>
<code> </code><code>public</code> <code>int</code> <code>read(</code><code>byte</code> <code>b[])</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>return</code> <code>read(b,</code><code>0</code><code>, b.length);</code>
<code> </code><code>}</code>
<code> </code><code>// 从输入流中读取数据最多len个字节,并存储在缓存数组b</code>
<code> </code><code>public</code> <code>int</code> <code>read(</code><code>byte</code> <code>b[],</code><code>int</code> <code>off,</code><code>int</code> <code>len)</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>if</code> <code>(b ==</code><code>null</code><code>) {</code>
<code> </code><code>throw</code> <code>new</code> <code>nullpointerexception();</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(off <</code><code>0</code> <code>|| len <</code><code>0</code> <code>|| len > b.length - off) {</code>
<code> </code><code>throw</code> <code>new</code> <code>indexoutofboundsexception();</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(len ==</code><code>0</code><code>) {</code>
<code> </code><code>return</code> <code>0</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>int</code> <code>c = read();</code>
<code> </code><code>if</code> <code>(c == -</code><code>1</code><code>) {</code>
<code> </code><code>return</code> <code>-</code><code>1</code><code>;</code>
<code> </code><code>b[off] = (</code><code>byte</code><code>)c;</code>
<code> </code><code>int</code> <code>i =</code><code>1</code><code>;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>for</code> <code>(; i < len ; i++) {</code>
<code> </code><code>c = read();</code>
<code> </code><code>if</code> <code>(c == -</code><code>1</code><code>) {</code>
<code> </code><code>break</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>b[off + i] = (</code><code>byte</code><code>)c;</code>
<code> </code><code>}</code>
<code> </code><code>}</code><code>catch</code> <code>(ioexception ee) {</code>
<code> </code><code>return</code> <code>i;</code>
<code> </code><code>// 跳过输入流中数据的n个字节</code>
<code> </code><code>public</code> <code>long</code> <code>skip(</code><code>long</code> <code>n)</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>long</code> <code>remaining = n;</code>
<code> </code><code>int</code> <code>nr;</code>
<code> </code><code>if</code> <code>(n <=</code><code>0</code><code>) {</code>
<code> </code><code>int</code> <code>size = (</code><code>int</code><code>)math.min(max_skip_buffer_size, remaining);</code>
<code> </code><code>byte</code><code>[] skipbuffer =</code><code>new</code> <code>byte</code><code>[size];</code>
<code> </code><code>while</code> <code>(remaining ></code><code>0</code><code>) {</code>
<code> </code><code>nr = read(skipbuffer,</code><code>0</code><code>, (</code><code>int</code><code>)math.min(size, remaining));</code>
<code> </code><code>if</code> <code>(nr <</code><code>0</code><code>) {</code>
<code> </code><code>break</code><code>;</code>
<code> </code><code>remaining -= nr;</code>
<code> </code><code>return</code> <code>n - remaining;</code>
<code> </code><code>// 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数</code>
<code> </code><code>public</code> <code>int</code> <code>available()</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>return</code> <code>0</code><code>;</code>
<code> </code><code>// 关闭此输入流,并释放与其关联的所有资源</code>
<code> </code><code>public</code> <code>void</code> <code>close()</code><code>throws</code> <code>ioexception {}</code>
<code> </code><code>// 在此输出流中标记当前位置</code>
<code> </code><code>public</code> <code>synchronized</code> <code>void</code> <code>mark(</code><code>int</code> <code>readlimit) {}</code>
<code> </code><code>// 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。</code>
<code> </code><code>public</code> <code>synchronized</code> <code>void</code> <code>reset()</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>throw</code> <code>new</code> <code>ioexception(</code><code>"mark/reset not supported"</code><code>);</code>
<code> </code><code>// 测试此输入流是否支持 mark 和 reset 方法</code>
<code> </code><code>public</code> <code>boolean</code> <code>marksupported() {</code>
<code> </code><code>return</code> <code>false</code><code>;</code>
<code>}</code>
其中,inputstream下面三个read方法才是核心方法:
<code>public</code> <code>abstract</code> <code>int</code> <code>read()</code>
抽象方法,没有具体实现。因为子类必须实现此方法的一个实现。这就是输入流的关键方法。
二者,可见下面两个read()方法都调用了这个方法子类的实现来完成功能的。
<code>public</code> <code>int</code> <code>read(</code><code>byte</code> <code>b[])</code>
该方法是表示从输入流中读取数据的一定数量字节,并存储在缓存字节数组b。其效果等同于调用了下面方法的实现:
<code>read(b,</code><code>0</code><code>, b.length)</code>
如果<code>b</code>的长度为 0,则不读取任何字节并返回 <code>0</code>;否则,尝试读取至少 1 字节。如果因为流位于文件末尾而没有可用的字节,则返回值 <code>-1</code>;否则,至少读取一个字节并将其存储在 <code>b</code> 中。
思考:这时候,怪不得很多时候, b != –1 或者 b != eof
<code>public</code> <code>int</code> <code>read(</code><code>byte</code> <code>b[],</code><code>int</code> <code>off,</code><code>int</code> <code>len)</code>
在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
该方法先进行校验,然后校验下个字节是否为空。如果校验通过后,
如下代码:
<code>int</code> <code>i =</code><code>1</code><code>;</code>
<code>try</code> <code>{</code>
<code> </code><code>for</code> <code>(; i < len ; i++) {</code>
<code> </code><code>c = read();</code>
<code> </code><code>break</code><code>;</code>
<code> </code><code>b[off + i] = (</code><code>byte</code><code>)c;</code>
<code>}</code><code>catch</code> <code>(ioexception ee) {</code>
将读取的第一个字节存储在元素 <code>b[off]</code> 中,下一个存储在 <code>b[off+1]</code> 中,依次类推。读取的字节数最多等于 <code>len</code>。设 k 为实际读取的字节数;这些字节将存储在 <code>b[off]</code> 到<code>b[off+</code>k<code>-1]</code> 的元素中,不影响 <code>b[off+</code>k<code>]</code> 到 <code>b[off+len-1]</code> 的元素。
因为有上面两个read的实现,所以这里inputstream设计为抽象类。
1. inputsream 对应着 outputstream 2. 看源码是享受人家写代码中流露的how