001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.io;
019:
020: /**
021: * InputStream is an abstract class for all byte input streams. It provides
022: * basic method implementations for reading bytes from a stream.
023: *
024: * @see OutputStream
025: */
026: public abstract class InputStream extends Object implements Closeable {
027:
028: private static byte[] skipBuf;
029:
030: /**
031: * This constructor does nothing interesting. Provided for signature
032: * compatibility.
033: */
034: public InputStream() {
035: /* empty */
036: }
037:
038: /**
039: * Answers a int representing then number of bytes that are available before
040: * this InputStream will block. This method always returns 0. Subclasses
041: * should override and indicate the correct number of bytes available.
042: *
043: * @return the number of bytes available before blocking.
044: *
045: * @throws IOException
046: * If an error occurs in this InputStream.
047: */
048: public int available() throws IOException {
049: return 0;
050: }
051:
052: /**
053: * Close the InputStream. Concrete implementations of this class should free
054: * any resources during close. This implementation does nothing.
055: *
056: * @throws IOException
057: * If an error occurs attempting to close this InputStream.
058: */
059: public void close() throws IOException {
060: /* empty */
061: }
062:
063: /**
064: * Set a Mark position in this InputStream. The parameter
065: * <code>readLimit</code> indicates how many bytes can be read before a
066: * mark is invalidated. Sending reset() will reposition the Stream back to
067: * the marked position provided <code>readLimit</code> has not been
068: * surpassed.
069: * <p>
070: * This default implementation does nothing and concrete subclasses must
071: * provide their own implementations.
072: *
073: * @param readlimit
074: * the number of bytes to be able to read before invalidating the
075: * mark.
076: */
077: public void mark(int readlimit) {
078: /* empty */
079: }
080:
081: /**
082: * Answers a boolean indicating whether or not this InputStream supports
083: * mark() and reset(). This class provides a default implementation which
084: * answers false.
085: *
086: * @return <code>true</code> if mark() and reset() are supported,
087: * <code>false</code> otherwise.
088: */
089: public boolean markSupported() {
090: return false;
091: }
092:
093: /**
094: * Reads a single byte from this InputStream and returns the result as an
095: * int. The low-order byte is returned or -1 of the end of stream was
096: * encountered. This abstract implementation must be provided by concrete
097: * subclasses.
098: *
099: * @return the byte read or -1 if end of stream.
100: *
101: * @throws IOException
102: * If the stream is already closed or another IOException
103: * occurs.
104: */
105: public abstract int read() throws IOException;
106:
107: /**
108: * Reads bytes from the Stream and stores them in byte array <code>b</code>.
109: * Answer the number of bytes actually read or -1 if no bytes were read and
110: * end of stream was encountered.
111: *
112: * @param b
113: * the byte array in which to store the read bytes.
114: * @return the number of bytes actually read or -1 if end of stream.
115: *
116: * @throws IOException
117: * If the stream is already closed or another IOException
118: * occurs.
119: */
120: public int read(byte b[]) throws IOException {
121: return read(b, 0, b.length);
122: }
123:
124: /**
125: * Reads at most <code>length</code> bytes from the Stream and stores them
126: * in byte array <code>b</code> starting at <code>offset</code>. Answer
127: * the number of bytes actually read or -1 if no bytes were read and end of
128: * stream was encountered.
129: *
130: * @param b
131: * the byte array in which to store the read bytes.
132: * @param offset
133: * the offset in <code>b</code> to store the read bytes.
134: * @param length
135: * the maximum number of bytes to store in <code>b</code>.
136: * @return the number of bytes actually read or -1 if end of stream.
137: *
138: * @throws IOException
139: * If the stream is already closed or another IOException
140: * occurs.
141: */
142: public int read(byte b[], int offset, int length)
143: throws IOException {
144: // avoid int overflow, check null b
145: if (offset > b.length || offset < 0 || length < 0
146: || length > b.length - offset) {
147: throw new ArrayIndexOutOfBoundsException();
148: }
149: for (int i = 0; i < length; i++) {
150: int c;
151: try {
152: if ((c = read()) == -1) {
153: return i == 0 ? -1 : i;
154: }
155: } catch (IOException e) {
156: if (i != 0) {
157: return i;
158: }
159: throw e;
160: }
161: b[offset + i] = (byte) c;
162: }
163: return length;
164: }
165:
166: /**
167: * Reset this InputStream to the last marked location. If the
168: * <code>readlimit</code> has been passed or no <code>mark</code> has
169: * been set, throw IOException. This implementation throws IOException and
170: * concrete subclasses should provide proper implementations.
171: *
172: * @throws IOException
173: * If the stream is already closed or another IOException
174: * occurs.
175: */
176: public synchronized void reset() throws IOException {
177: throw new IOException();
178: }
179:
180: /**
181: * Skips <code>n</code> number of bytes in this InputStream. Subsequent
182: * <code>read()</code>'s will not return these bytes unless
183: * <code>reset()</code> is used. This method may perform multiple reads to
184: * read <code>n</code> bytes. This default implementation reads
185: * <code>n</code> bytes into a temporary buffer. Concrete subclasses
186: * should provide their own implementation.
187: *
188: * @param n
189: * the number of bytes to skip.
190: * @return the number of bytes actually skipped.
191: *
192: * @throws IOException
193: * If the stream is already closed or another IOException
194: * occurs.
195: */
196: public long skip(long n) throws IOException {
197: if (n <= 0) {
198: return 0;
199: }
200: long skipped = 0;
201: int toRead = n < 4096 ? (int) n : 4096;
202: if (skipBuf == null || skipBuf.length < toRead) {
203: skipBuf = new byte[toRead];
204: }
205: while (skipped < n) {
206: int read = read(skipBuf, 0, toRead);
207: if (read == -1) {
208: return skipped;
209: }
210: skipped += read;
211: if (read < toRead) {
212: return skipped;
213: }
214: if (n - skipped < toRead) {
215: toRead = (int) (n - skipped);
216: }
217: }
218: return skipped;
219: }
220: }
|