Skip to main content

Add SequenceReader in java.io

No replies
mozer
Offline
Joined: 2003-12-06

To be symetric with java.io.SequenceInputStream, let's implements SequenceReader.

Here is the source you could use

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* @author duke
*
*/
public class SequenceReader extends Reader {

Iterator readerIterator;

Reader reader;

/**
* Initializes a newly created SequenceReader by
* remembering the argument, which must be a List
* that produces objects whose run-time type is Reader.
* The readers that are produced by the enumeration will be read, in
* order, to provide the bytes to be read from this
* SequenceReader. After each reader from the
* list is exhausted, it is closed by calling its close
* method.
*
* @param readerList
* an list of reader.
* @see java.util.List
*/
public SequenceReader(List readerList) {
this.readerIterator = readerList.iterator();
try {
nextReader();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}

/**
* Initializes a newly created SequenceReader by
* remembering the two arguments, which will be read in order, first
* iReader1 and then iReader2, to provide
* the bytes to be read from this SequenceReader.
*
* @param iReader1
* the first reader to read.
* @param iReader2
* the second reader to read.
*/
public SequenceReader(Reader iReader1, Reader iReader2) {
List l = new ArrayList(2);
l.add(iReader1);
l.add(iReader2);
this.readerIterator = l.iterator();
try {
nextReader();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}

/**
* Continues reading in the next reader if an EOF is reached.
*/
final void nextReader() throws IOException {
if (this.reader != null) {
this.reader.close();
}
if (this.readerIterator.hasNext()) {
this.reader = (Reader) this.readerIterator.next();
if (this.reader == null) { throw new NullPointerException(); }
} else
this.reader = null;

}

/**
* Reads the next char from this reader. The char is returned
* as an int in the range 0x0000 to
* 0xffff. If no char is available because the end of the
* stream has been reached, the value -1 is returned. This
* method blocks until input data is available, the end of the stream is
* detected, or an exception is thrown.
*
* This method tries to read one character from the current substream. If it
* reaches the end of the stream, it calls the close method
* of the current substream and begins reading from the next substream.
*
* @return the next char, or -1 if the end of the
* stream is reached.
* @exception IOException
* if an I/O error occurs.
*/
public int read() throws IOException {
if (this.reader == null) { return -1; }
int c = this.reader.read();
if (c == -1) {
nextReader();
return read();
}
return c;
}

/**
* Reads up to len char of data from this reader into
* an array of char. This method blocks until at least 1 char of input is
* available. If the first argument is null, up to
* len char are read and discarded.
*
* The read method of SequenceInputStream
* tries to read the data from the current substream. If it fails to read
* any characters because the substream has reached the end of the stream,
* it calls the close method of the current substream and
* begins reading from the next substream.
*
* @param b
* the buffer into which the data is read.
* @param off
* the start offset of the data.
* @param len
* the maximum number of bytes read.
* @return int the number of bytes read.
* @exception IOException
* if an I/O error occurs.
*/
public int read(char b[], int off, int len) throws IOException {
if (this.reader == null) {
return -1;
} else if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0)
|| ((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) { return 0; }

int n = this.reader.read(b, off, len);
if (n <= 0) {
nextReader();
return read(b, off, len);
}
return n;
}

/**
* Closes this reader and releases any system resources associated
* with the reader. A closed SequenceReader cannot
* perform input operations and cannot be reopened.
*
* If this stream was created from a list, all remaining elements
* are requested from the list and closed before the
* close method returns.
*
* @exception IOException
* if an I/O error occurs.
*/
public void close() throws IOException {
do {
nextReader();
} while (this.reader != null);
}

}