SequenceInputStream
creates a single input stream from multiple input sources. This example program uses SequenceInputStream
to implement a concatenation utility that sequentially concatenates files together in the order they are listed on the command line. So lets first create the Utility class which perform this application, say we call it ListOfFiles which takes list of file names in its constructor, and then concatenates them by creating a new InputStream for every filename listed as argument.
Creating the Utility Class
import java.util.*;
import java.io.*;
public class ListOfFiles implements Enumeration {
private String[] listOfFiles;
private int current = 0;
public ListOfFiles(String[] listOfFiles) {
this.listOfFiles = listOfFiles;
}
public boolean hasMoreElements() {
if (current < listOfFiles.length)
return true;
else
return false;
}
public Object nextElement() {
InputStream in = null;
if (!hasMoreElements())
throw new NoSuchElementException("No more files.");
else {
String nextElement = listOfFiles[current];
current++;
try {
in = new FileInputStream(nextElement);
} catch (FileNotFoundException e) {
System.err.println("ListOfFiles: Can't open " + nextElement);
}
}
return in;
}
}
ListOfFiles implements the Enumeration
interface. You'll see how this comes into play as we walk through the rest of the program.
Using this Utility class
import java.io.*;
public class Concatenate {
public static void main(String[] args) throws IOException {
ListOfFiles mylist = new ListOfFiles(args);
SequenceInputStream s = new SequenceInputStream(mylist);
int c;
while ((c = s.read()) != -1)
System.out.write(c);
s.close();
}
}
After the main
method creates the SequenceInputStream
, it reads from it one byte at a time. When the SequenceInputStream
needs an InputStream
from a new source (such as for the first byte read or when it runs off the end of the current input stream), it calls nextElement
on the Enumeration
object to get the next InputStream. ListOfFiles
creates FileInputStream
objects lazily, meaning that whenever SequenceInputStream
calls nextElement
, ListOfFiles
opens a FileInputStream
on the next filename in the list and returns the stream. When the ListOfFiles
runs out of files to read (it has no more elements), nextElement
returns null, and the call to SequenceInputStream
's read
method returns -1 to indicate the end of input.
Concatenate
simply echos all the data read from the SequenceInputStream
to the standard output.
No comments:
Post a Comment