import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.NoSuchElementException; import java.util.StringTokenizer; import java.util.Vector; import org.shodor.util11.StrLib; /** * Handles File input/ouput. */ public class FileIO { public static final String FILE_EXTENSION = "txt"; private static final String DELIMITERS = "\t, "; /** * Accepts a data file as input and returns a vector, each element * representing an experimental condition. */ public static Vector loadExperimentalConditionFile(File datafile) { Vector retValue = new Vector(); String[] header = new String[0]; // Human descriptions of property // fields. boolean headerRead = false; BufferedReader in; try { in = new BufferedReader(new InputStreamReader( new BufferedInputStream(new FileInputStream(datafile)))); } catch (FileNotFoundException fnfe) { System.out .println("The file: " + datafile.getName() + " cannot be found. Returning empty experimental conditions."); return retValue; } String input; int lineNumber = 0; int ignorefields = 2; // participant ID and experimental condition ID try { while ((input = in.readLine()) != null) { lineNumber++; StringTokenizer st = new StringTokenizer(input, DELIMITERS, true); // Include Delimeter in token to detect blank // cells. if (!headerRead) { // Read and store the property descriptions. /** * Ignore the first 4 tokens (2 tabs and participant ID * header and experimental ID header). Then divide the * remaining tokens by two and round up to ignore tokens and * get the length of the header array. */ int ignoretokens = 2 * ignorefields; // Ignore tabs if (st.countTokens() % 2 == 0) { header = new String[(st.countTokens() - ignoretokens) / 2]; } else { header = new String[((st.countTokens() - ignoretokens) / 2) + 1]; } // Do not need participant ID header text or experimental // condition ID header or included tabs. for (int i = 0; i < ignoretokens; i++) { st.nextToken(); } for (int i = 0; i < header.length; i++) { try { header[i] = st.nextToken().trim(); if (st.hasMoreTokens()) { st.nextToken(); } } catch (NoSuchElementException nsee) { System.out.println("No such element for header " + i + ", header.length: " + header.length + ", tokens: " + st.countTokens()); } } headerRead = true; } else { int participantID = (Integer .parseInt(st.nextToken().trim())); st.nextToken(); // Ignore delimeter. Assume all participant // and experimental condition IDs are // entered. int conditionID = (Integer.parseInt(st.nextToken().trim())); st.nextToken(); // Ignore delimeter. Assume all participant // and experimental condition IDs are // entered. double[] fields = new double[header.length]; for (int i = 0; i < fields.length; i++) { String nextToken = ""; try { nextToken = st.nextToken().trim(); } catch (NoSuchElementException nsee) { // The line has no more tokens and the remaining // cells are blank. if (TimeSeries.DEBUG) { System.out .println("No remaining tokens. Returning Double.NaN. "+"line number: " + lineNumber + ", column number " + (i + 1 + ignorefields)+""); } fields[i] = Double.NaN; continue; } if (nextToken.length() == 0) { // The cell is blank. No data is in the cell. if (TimeSeries.DEBUG) { System.out.println("Blank Cell!!!"); System.out.println("line number: " + lineNumber + ", column number " + (i + 1 + ignorefields)); } fields[i] = Double.NaN; } else { try { fields[i] = (new Double(nextToken)) .doubleValue(); } catch (NumberFormatException nfe) { // XXX May // want // to throw // exception and // display a // pop-up System.out .println("Error reading numerical value from data set."); nfe.printStackTrace(); return null; } // Advance tokenizer passed delimeter if not at the // end. if (st.hasMoreTokens()) { st.nextToken(); } } } // Is there already an element in the retValue vector // corresponding to the experimental condition ID? int previousConditionIndex = -1; for (int i = 0; i < retValue.size(); i++) { if (conditionID == ((ExperimentalCondition) retValue .elementAt(i)).getExperimentalConditionID()) { previousConditionIndex = i; } } // If yes, add the trial to the experimental condition // vector. if (previousConditionIndex != -1) { ExperimentalCondition ec = (ExperimentalCondition) retValue .elementAt(previousConditionIndex); ec.addTrial(participantID, fields); } else { // If no, add a new ExperimentalCondition object // to the experimental condition vector and then // add the data fields to the experimental // condition object. retValue.addElement(new ExperimentalCondition( conditionID, header)); ExperimentalCondition ec = (ExperimentalCondition) retValue .lastElement(); ec.addTrial(participantID, fields); } } } } catch (IOException ioe) { System.out .println("ERROR: Parsing data file " + datafile.getName()); System.out.println(ioe.getMessage()); ioe.printStackTrace(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } try { in.close(); } catch (IOException ioe) { System.out.println("Error closing datafile."); System.out.println(ioe.getMessage()); ioe.printStackTrace(); } return retValue; } }