KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > SequenceInputStream


1 /*
2  * @(#)SequenceInputStream.java 1.28 04/05/12
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10 import java.io.InputStream JavaDoc;
11 import java.util.Enumeration JavaDoc;
12 import java.util.Vector JavaDoc;
13
14 /**
15  * A <code>SequenceInputStream</code> represents
16  * the logical concatenation of other input
17  * streams. It starts out with an ordered
18  * collection of input streams and reads from
19  * the first one until end of file is reached,
20  * whereupon it reads from the second one,
21  * and so on, until end of file is reached
22  * on the last of the contained input streams.
23  *
24  * @author Author van Hoff
25  * @version 1.28, 05/12/04
26  * @since JDK1.0
27  */

28 public
29 class SequenceInputStream extends InputStream JavaDoc {
30     Enumeration JavaDoc e;
31     InputStream JavaDoc in;
32
33     /**
34      * Initializes a newly created <code>SequenceInputStream</code>
35      * by remembering the argument, which must
36      * be an <code>Enumeration</code> that produces
37      * objects whose run-time type is <code>InputStream</code>.
38      * The input streams that are produced by
39      * the enumeration will be read, in order,
40      * to provide the bytes to be read from this
41      * <code>SequenceInputStream</code>. After
42      * each input stream from the enumeration
43      * is exhausted, it is closed by calling its
44      * <code>close</code> method.
45      *
46      * @param e an enumeration of input streams.
47      * @see java.util.Enumeration
48      */

49     public SequenceInputStream(Enumeration JavaDoc<? extends InputStream JavaDoc> e) {
50     this.e = e;
51     try {
52         nextStream();
53     } catch (IOException JavaDoc ex) {
54         // This should never happen
55
throw new Error JavaDoc("panic");
56     }
57     }
58
59     /**
60      * Initializes a newly
61      * created <code>SequenceInputStream</code>
62      * by remembering the two arguments, which
63      * will be read in order, first <code>s1</code>
64      * and then <code>s2</code>, to provide the
65      * bytes to be read from this <code>SequenceInputStream</code>.
66      *
67      * @param s1 the first input stream to read.
68      * @param s2 the second input stream to read.
69      */

70     public SequenceInputStream(InputStream JavaDoc s1, InputStream JavaDoc s2) {
71     Vector JavaDoc v = new Vector JavaDoc(2);
72
73     v.addElement(s1);
74     v.addElement(s2);
75     e = v.elements();
76     try {
77         nextStream();
78     } catch (IOException JavaDoc ex) {
79         // This should never happen
80
throw new Error JavaDoc("panic");
81     }
82     }
83
84     /**
85      * Continues reading in the next stream if an EOF is reached.
86      */

87     final void nextStream() throws IOException JavaDoc {
88     if (in != null) {
89         in.close();
90     }
91
92         if (e.hasMoreElements()) {
93             in = (InputStream JavaDoc) e.nextElement();
94             if (in == null)
95                 throw new NullPointerException JavaDoc();
96         }
97         else in = null;
98
99     }
100
101     /**
102      * Returns the number of bytes available on the current stream.
103      *
104      * @since JDK1.1
105      */

106     public int available() throws IOException JavaDoc {
107     if(in == null) {
108         return 0; // no way to signal EOF from available()
109
}
110     return in.available();
111     }
112
113     /**
114      * Reads the next byte of data from this input stream. The byte is
115      * returned as an <code>int</code> in the range <code>0</code> to
116      * <code>255</code>. If no byte is available because the end of the
117      * stream has been reached, the value <code>-1</code> is returned.
118      * This method blocks until input data is available, the end of the
119      * stream is detected, or an exception is thrown.
120      * <p>
121      * This method
122      * tries to read one character from the current substream. If it
123      * reaches the end of the stream, it calls the <code>close</code>
124      * method of the current substream and begins reading from the next
125      * substream.
126      *
127      * @return the next byte of data, or <code>-1</code> if the end of the
128      * stream is reached.
129      * @exception IOException if an I/O error occurs.
130      */

131     public int read() throws IOException JavaDoc {
132     if (in == null) {
133         return -1;
134     }
135     int c = in.read();
136     if (c == -1) {
137         nextStream();
138         return read();
139     }
140     return c;
141     }
142
143     /**
144      * Reads up to <code>len</code> bytes of data from this input stream
145      * into an array of bytes. This method blocks until at least 1 byte
146      * of input is available. If the first argument is <code>null</code>,
147      * up to <code>len</code> bytes are read and discarded.
148      * <p>
149      * The <code>read</code> method of <code>SequenceInputStream</code>
150      * tries to read the data from the current substream. If it fails to
151      * read any characters because the substream has reached the end of
152      * the stream, it calls the <code>close</code> method of the current
153      * substream and begins reading from the next substream.
154      *
155      * @param b the buffer into which the data is read.
156      * @param off the start offset of the data.
157      * @param len the maximum number of bytes read.
158      * @return int the number of bytes read.
159      * @exception IOException if an I/O error occurs.
160      */

161     public int read(byte b[], int off, int len) throws IOException JavaDoc {
162     if (in == null) {
163         return -1;
164     } else if (b == null) {
165         throw new NullPointerException JavaDoc();
166     } else if ((off < 0) || (off > b.length) || (len < 0) ||
167            ((off + len) > b.length) || ((off + len) < 0)) {
168         throw new IndexOutOfBoundsException JavaDoc();
169     } else if (len == 0) {
170         return 0;
171     }
172
173     int n = in.read(b, off, len);
174     if (n <= 0) {
175         nextStream();
176         return read(b, off, len);
177     }
178     return n;
179     }
180
181     /**
182      * Closes this input stream and releases any system resources
183      * associated with the stream.
184      * A closed <code>SequenceInputStream</code>
185      * cannot perform input operations and cannot
186      * be reopened.
187      * <p>
188      * If this stream was created
189      * from an enumeration, all remaining elements
190      * are requested from the enumeration and closed
191      * before the <code>close</code> method returns.
192      * of <code>InputStream</code> .
193      *
194      * @exception IOException if an I/O error occurs.
195      */

196     public void close() throws IOException JavaDoc {
197     do {
198         nextStream();
199     } while (in != null);
200     }
201 }
202
Popular Tags