The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Essential Java Classes
Lesson: I/O: Reading and Writing (but no 'rithmetic)

How to Concatenate Files

The SequenceInputStream (in the API reference documentation) creates a single input stream from multiple input sources. This example program, Concatenate (in a .java source file), uses SequenceInputStream to implement a concatenation utility that sequentially concatenates files together in the order they are listed on the command line.

This is the controlling class of the Concatenate utility:

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();
    }
}
First, the Concatenate utility creates a ListOfFiles object named mylist which is initialized from the command line arguments entered by the user. The command line arguments list the files to be concatenated together. The mylist object is an enumeration that SequenceInputStream uses to get a new InputStream whenever it needs one.
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 (in the API reference documentation) interface. You'll see how this comes into play as you walk through the rest of the program.

After creating the SequenceInputStream, the main method reads from that stream one byte at a time. When it 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, the SequenceInputStream calls nextElement on the Enumeration object to get the next InputStream. ListOfFiles creates FileInputStream objects lazily. This means that whenever SequenceInputStream calls nextElement, ListOfFiles opens a FileInputStream on the next file name 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.


Try this:  Try running Concatenate on the farrago.txt (in a .java source file) and words.txt (in a .java source file) files; both are used as input to other examples in this lesson.

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved.