package textfile; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.List; /* * Created on Apr 29, 2004 */ /** A class which can locate and read a delimited text file and make the * fields available line by line. By default, the file is assumed to be * tab-delimited (has tabs separating the string fields on each line). * Alternatively, another delimiter can be designated. There * can be any number of fields on each line. Each field is taken to be a * String. Within a field, no trimming or parsing is done. This class is * just a wrapper for a DelimitedTextReader. * @author dickey */ public class DelimitedTextFile { /** The underlying reader. */ private DelimitedTextReader textReader; /** The actual path or URL of the file, if it was successfully located. */ private String absPath; /** the number of lines successfully read so far; "read" * means delivered to the user (we might be ahead internally). */ private int linenum = 0; /** The string passed to the DelimitedTextReader to split the lines. */ private String delimiter; /** The default delimiter used for splitting lines of text. */ public static final String DEFAULT_DELIMITER = "\t"; /** Given a file name, find the file it refers to it and make it ready * for read-access; the field delimiter is set to be the TAB character. * For more information, see the 2-argument constructor. * @param filename a full or partial file name or URL. */ public DelimitedTextFile(String filename) { this(filename, DEFAULT_DELIMITER); } /** Given a file name, find the file it refers to it and make it ready * for read-access; the field delimiter is set to be the parameter value. * Look first on the class path; after that, bring up a file chooser * as a last resort. * If no file can be opened, or there is an error on the file, then * a console message is printed; in this case the * DelimitedTextFile object is effectively an empty file -- any calls to * retrieve data will return null. * @param filename a full or partial filename or URL; may not be * empty or null. * @param delimiter the string which delimits fields on each line of * the file. This is typically a single character, such as TAB, but * it can be any regular expression; may not be empty or null. * @throws IllegalArgumentException if a parameter value is bad. * */ public DelimitedTextFile(String filename, String delimiter) { if (delimiter == null || delimiter.length() == 0) { throw new IllegalArgumentException("delimiter cannot be empty or null"); } if (filename == null || filename.length() == 0) { throw new IllegalArgumentException("file name cannot be empty or null"); } this.delimiter = delimiter; String partialPath = filename.trim(); FileOrURLInputStream iStream = new FileOrURLInputStream(partialPath, FileFinderOption.PROMPT_FOR_FILE); if (iStream == null) { System.out.println("No file located or chosen for " + filename); } else { BufferedReader br = new BufferedReader( new InputStreamReader(iStream)); textReader = new DelimitedTextReader(br, this.delimiter); this.absPath = iStream.getFileID(); } } /** Read the next line of the file and parse it into fields. * Each field is terminated with the delimiter string for this file, or * with end-of-file. The strings in the array may be empty but are * never null. If the last character(s) on the line exactly * match the delimiter string, then the last string of the array is * the empty string. * * @return the fields of the file, as strings, or null if there is no * more data, or if any error is encountered. */ public String[] readLineAsFieldArray() { try { String[] thisLineFields = this.textReader.readLineAsFieldArray(); this.linenum++; return thisLineFields; } catch (Exception e) { return null; } } /** Return the data of the current line as a list of Strings; see * readLineAsFieldArray(). * @return a list with data equivalent to readLineAsFieldArray() */ public List readLineAsFieldList() { try { List thisLineFields = this.textReader.readLineAsFieldList(); this.linenum++; return thisLineFields; } catch (Exception e) { return null; } } /** Tells the number of the most recently read line. * * @return the line number of the most recently read line; the first * line of the file is numbered 1; a return value of 0 means no lines * have been read yet. * */ public int getLineNum() { return this.linenum; } /** Tells the name of the underlying file; may be a path or URL. * * @return the identifier (full path or URL) * of the underlying file, which might be different * from the path or id as requested; return null if the file has not * actually be located. */ public String getFileName() { return this.absPath; } /** Produce a summary of this object. * @return a string summarizing the status of this object. */ public String toString() { String retStr = this.getClass().getName() + "["; retStr += "line=" + this.linenum + " file=" + this.absPath; retStr += "]"; return retStr; } }