Mercurial Hosting > luan
annotate src/goodjava/io/BufferedInputStream.java @ 1489:fe237d72b234
improve BufferedInputStream
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 02 May 2020 16:28:24 -0600 |
parents | 97740900c820 |
children | 91c167099462 |
rev | line source |
---|---|
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1 /* |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
4 */ |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
5 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
6 package goodjava.io; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
7 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
8 import java.io.InputStream; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
9 import java.io.FilterInputStream; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
10 import java.io.IOException; |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
11 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
12 /** |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
13 * A <code>BufferedInputStream</code> adds |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
14 * functionality to another input stream-namely, |
1480 | 15 * the ability to buffer the input. When the <code>BufferedInputStream</code> |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
16 * is created, an internal buffer array is |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
17 * created. As bytes from the stream are read |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
18 * or skipped, the internal buffer is refilled |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
19 * as necessary from the contained input stream, |
1480 | 20 * many bytes at a time. |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
21 * |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
22 * @author Arthur van Hoff |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
23 * @since JDK1.0 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
24 */ |
1480 | 25 public final class BufferedInputStream extends FilterInputStream { |
26 private final byte buf[]; | |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
27 |
1479 | 28 /** |
29 * The index one greater than the index of the last valid byte in | |
30 * the buffer. | |
31 * This value is always | |
32 * in the range <code>0</code> through <code>buf.length</code>; | |
33 * elements <code>buf[0]</code> through <code>buf[count-1] | |
34 * </code>contain buffered input data obtained | |
1480 | 35 * from the underlying input stream. |
1479 | 36 */ |
1480 | 37 private int count; |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
38 |
1479 | 39 /** |
40 * The current position in the buffer. This is the index of the next | |
41 * character to be read from the <code>buf</code> array. | |
42 * <p> | |
43 * This value is always in the range <code>0</code> | |
44 * through <code>count</code>. If it is less | |
45 * than <code>count</code>, then <code>buf[pos]</code> | |
46 * is the next byte to be supplied as input; | |
47 * if it is equal to <code>count</code>, then | |
48 * the next <code>read</code> or <code>skip</code> | |
49 * operation will require more bytes to be | |
50 * read from the contained input stream. | |
51 * | |
52 * @see java.io.BufferedInputStream#buf | |
53 */ | |
1480 | 54 private int pos; |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
55 |
1479 | 56 /** |
57 * Creates a <code>BufferedInputStream</code> | |
58 * and saves its argument, the input stream | |
59 * <code>in</code>, for later use. An internal | |
60 * buffer array is created and stored in <code>buf</code>. | |
61 * | |
62 * @param in the underlying input stream. | |
63 */ | |
64 public BufferedInputStream(InputStream in) { | |
1483 | 65 this(in, 8192); |
1479 | 66 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
67 |
1479 | 68 /** |
69 * Creates a <code>BufferedInputStream</code> | |
70 * with the specified buffer size, | |
71 * and saves its argument, the input stream | |
72 * <code>in</code>, for later use. An internal | |
73 * buffer array of length <code>size</code> | |
74 * is created and stored in <code>buf</code>. | |
75 * | |
76 * @param in the underlying input stream. | |
77 * @param size the buffer size. | |
78 */ | |
79 public BufferedInputStream(InputStream in, int size) { | |
80 super(in); | |
81 buf = new byte[size]; | |
82 } | |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
83 |
1479 | 84 /** |
1480 | 85 * Fills the buffer with more data. |
1479 | 86 * Assumes that it is being called by a synchronized method. |
87 * This method also assumes that all data has already been read in, | |
88 * hence pos > count. | |
89 */ | |
90 private void fill() throws IOException { | |
1480 | 91 pos = 0; |
92 count = 0; | |
93 int n = super.read(buf, 0, buf.length); | |
1479 | 94 if (n > 0) |
1480 | 95 count = n; |
1479 | 96 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
97 |
1479 | 98 /** |
99 * See | |
100 * the general contract of the <code>read</code> | |
101 * method of <code>InputStream</code>. | |
102 * | |
103 * @return the next byte of data, or <code>-1</code> if the end of the | |
104 * stream is reached. | |
105 * @exception IOException if this input stream has been closed by | |
106 * invoking its {@link #close()} method, | |
107 * or an I/O error occurs. | |
108 * @see java.io.FilterInputStream#in | |
109 */ | |
110 public synchronized int read() throws IOException { | |
111 if (pos >= count) { | |
112 fill(); | |
113 if (pos >= count) | |
114 return -1; | |
115 } | |
1480 | 116 return buf[pos++] & 0xff; |
1479 | 117 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
118 |
1479 | 119 /** |
120 * Read characters into a portion of an array, reading from the underlying | |
121 * stream at most once if necessary. | |
122 */ | |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
123 private int read1(byte[] b, int off, int len) throws IOException { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
124 int cnt = 0; |
1479 | 125 int avail = count - pos; |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
126 if( avail > 0 ) { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
127 cnt = (avail < len) ? avail : len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
128 System.arraycopy(buf, pos, b, off, cnt); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
129 pos += cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
130 len -= cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
131 if( len == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
132 return cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
133 off += cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
134 } |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
135 if (len >= buf.length) { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
136 return cnt + Math.max( 0, super.read(b, off, len) ); |
1479 | 137 } |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
138 fill(); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
139 if (count <= 0) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
140 return cnt; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
141 System.arraycopy(buf, 0, b, off, len); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
142 pos += len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
143 return cnt + len; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
144 } |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
145 |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
146 public synchronized int read(byte[] b, int off, int len) throws IOException { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
147 if( len == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
148 return 0; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
149 int n = read1(b,off,len); |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
150 return n==0 ? -1 : n; |
1479 | 151 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
152 |
1479 | 153 /** |
154 * See the general contract of the <code>skip</code> | |
155 * method of <code>InputStream</code>. | |
156 * | |
157 * @exception IOException if the stream does not support seek, | |
158 * or if this input stream has been closed by | |
159 * invoking its {@link #close()} method, or an | |
160 * I/O error occurs. | |
161 */ | |
162 public synchronized long skip(long n) throws IOException { | |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
163 if( n <= 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
164 return 0; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
165 long skipped = 0; |
1479 | 166 long avail = count - pos; |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
167 if( avail > 0 ) { |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
168 skipped = (avail < n) ? avail : n; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
169 pos += skipped; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
170 n -= skipped; |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
171 if( n == 0 ) |
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
172 return skipped; |
1479 | 173 } |
1489
fe237d72b234
improve BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
1483
diff
changeset
|
174 return skipped + super.skip(n); |
1479 | 175 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
176 |
1479 | 177 /** |
178 * Returns an estimate of the number of bytes that can be read (or | |
179 * skipped over) from this input stream without blocking by the next | |
180 * invocation of a method for this input stream. The next invocation might be | |
181 * the same thread or another thread. A single read or skip of this | |
182 * many bytes will not block, but may read or skip fewer bytes. | |
183 * <p> | |
184 * This method returns the sum of the number of bytes remaining to be read in | |
185 * the buffer (<code>count - pos</code>) and the result of calling the | |
186 * {@link java.io.FilterInputStream#in in}.available(). | |
187 * | |
188 * @return an estimate of the number of bytes that can be read (or skipped | |
189 * over) from this input stream without blocking. | |
190 * @exception IOException if this input stream has been closed by | |
191 * invoking its {@link #close()} method, | |
192 * or an I/O error occurs. | |
193 */ | |
194 public synchronized int available() throws IOException { | |
195 int n = count - pos; | |
1480 | 196 int avail = super.available(); |
1479 | 197 return n > (Integer.MAX_VALUE - avail) |
198 ? Integer.MAX_VALUE | |
199 : n + avail; | |
200 } | |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
201 |
1480 | 202 public void mark(int readlimit) {} |
203 | |
204 public void reset() throws IOException { | |
205 throw new IOException("mark/reset not supported"); | |
1479 | 206 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
207 |
1479 | 208 public boolean markSupported() { |
1480 | 209 return false; |
1479 | 210 } |
1478
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
211 |
37e582f2e266
clone BufferedInputStream
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
212 } |