Readers Writers  «Prev  Next»


Lesson 6Line numbering
ObjectiveWrite a program that uses the LineNumberReader class and readLine() methods to keep track of the line you are currently reading.

LineNumberReader class and readLine() methods in Java


The java.io.LineNumberReader class is a subclass of java.io.BufferedReader that keeps track of which line you're currently reading. It has all the methods of BufferedReader, including readLine().
The LineNumberReader class also has two constructors, plus the getLineNumber() and setLineNumber() methods:
public LineNumberReader(Reader in)

public LineNumberReader(Reader in, int size)

public void setLineNumber(int lineNumber)

public int getLineNumber()
The setLineNumber() method does not change the line that you're reading in the file. It just changes the value getLineNumber() returns. For example, it would allow you to start counting from -5 if you knew there were six lines of header data you did not want to count.

The Reader classes are actually subclassed from an abstract ContLineReader subclass, which I will present first (Example 5-6). This class encapsulates the basic functionality for keeping track of lines that need to be joined together, and for enabling/disabling the continuation processing.
Example 5-6. ContLineReader.java
import java.io.*;
/** Subclass of LineNumberReader to allow reading of continued lines
* using the readLine() method. The other Reader methods (readInt( )) etc.)
* must not be used. Must subclass to provide the actual implementation
* of readLine( ).
*/
public abstract class ContLineReader extends LineNumberReader {
/** Line number of first line in current (possibly continued) line */
 protected int firstLineNumber = 0;
 /** True if handling continuations, false if not; false == "PRE" mode */
 protected boolean doContinue = true;
 /** Set the continuation mode */
 public void setContinuationMode(boolean b) {
 doContinue = b;
}
/** Get the continuation mode */
public boolean isContinuation( ) {
 return doContinue;
}
/** Read one (possibly continued) line, stripping out the \ that
* marks the end of each line but the last in a sequence.
*/
public abstract String readLine( ) throws IOException;
 /** Read one real line. Provided as a convenience for the subclasses, so they don't embarass themselves 
 * trying to call "super.readLine( )" which isn't very practical */
public String readPhysicalLine( ) throws IOException {
 return super.readLine( );
}
// Can NOT override getLineNumber in this class to return the # of the beginning 
// of the continued line, since the subclasses all call super.getLineNumber
/** Construct a ContLineReader with the default input-buffer size. */
 public ContLineReader(Reader in) {
  super(in);
 }
 /** Construct a ContLineReader using the given input-buffer size. */
 public ContLineReader(Reader in, int sz) {
  super(in, sz);
 }
 // Methods that do NOT work - redirect straight to parent
 /** Read a single character, returned as an int. */
 public int read( ) throws IOException {
  return super.read( );
 }
 /** Read characters into a portion of an array. */
 public int read(char[] cbuf, int off, int len) throws IOException {
  return super.read(cbuf, off, len);
 }
 public boolean markSupported( ) {
  return false;
 }
}

The ContLineReader class ends with code for handling the read( ) calls so that the class will work correctly. The IndentContLineReader class extends this to allow merging of lines based on indentation.

Java line Number Reader - Exercise

Click the Exercise link below to write a program that uses a LineNumberReader and readLine() to read all files named on the command line, line by line, and copy them to System.out, prefixing each line with its line number.
Java line Number Reader - Exercise