User Tools

Site Tools


private:filereader

This is an old revision of the document!


How to use the FileReader to read complex text files

The FileReader was built to facilitate the reading of parameters, measurements or inventory text files.

These files may contain keyword parameters and rows with values in columns separated by tabs (e.g. 2 columns below):

# Simeo-Principes command file

parameterFileName = PhoenixRomana.txt

plantAge = 200
plantSeed = 1

archimed1ConfigFileName = archimed1.config

# Pattern coordinates in m
pattern = ((0,10);(10,0))
patternBounds = ((-5,-5);(15,15))

# simName	simulationParameters
sim1	PinnaeDistance_1(2D;1;(0:2.3);(50:10);(100:2))
sim2	PinnaeDistance_1(2D;1;(0:6);(50:15);(100:4))

To read such a file, it is possible to write a subclass of FileLoader where the public fields are expected to be automatically loaded from the file.

  • each public field will be searched in the file for a keyword parameter with same name and its type will be checked (e.g. error if an int is expected and a double is found in the file)
  • each public List<SomeType> will be fed with the lines in the file matching the SomeType pattern. SomeType must extend jeeb.lib.util.Record and provide a constructor with a String parameter relying on the constructor of Record, so that an automatic type-matching method is run

The lines of the file starting with a '#' comment mark and blank lines are ignored.

Possible types for the public fields in the loader:

  • byte, short, int, long
  • float, double
  • boolean
  • char
  • String
  • a subclass of Record

Possible types for the public lists:

  • List<SomeType> (only List is possible, no other collection like Set…)
  • SomeType must extend Record and chain to its constructor (String) (see the example below)

Here is an example of loader for the file upper:

package jeeb.simeo.module.simeoeditor.scripts;
 
import java.util.List;
 
import jeeb.lib.util.FileLoader;
import jeeb.lib.util.Record;
 
/**
 * Testing the new FileLoader class.
 * 
 * @author F. de Coligny - December 2013
 */
public class ScriptRaphael2013FileLoader extends FileLoader {
 
	public String parameterFileName;
	public int plantAge;
	public int plantSeed;
	public String archimed1ConfigFileName;
	public String pattern;
	public String patternBounds;
 
	public List<SimRecord> simRecords;
 
	protected void checks() throws Exception {
 
		check(plantAge > 0, "plantAge must be > 0");
		check(plantSeed >= 0, "plantSeed must be >= 0");
 
		if (simRecords.isEmpty ()) {
			report ("The simRecords list should not be empty");
			throw new Exception (report.toString ());
		}
 
	}
 
	// A line in the command file
	static public class SimRecord extends Record {
 
		// e.g. sim1
		public String simName;
		// e.g. PinnaeDistance_1(2D;1;(0:2.3);(50:10);(100:2)) !
		// FrondNervureLength_1(2D;1;(1:100);(175:400))
		public String simulationParameters;
 
		public SimRecord(String line) throws Exception {
			super(line);
		}
	}
 
}

This loader may be used like below:

	(...)
	// Interpret command file
	ScriptRaphael2013FileLoader loader = new ScriptRaphael2013FileLoader();
	String loaderReport = loader.load(commandFileName);
 
	if (!loader.succeeded()) {
		System.out.println(loaderReport);
		throw new Exception ();
	}
 
	// commandFileName = reader.getCommandFileName();
	parameterFileName = loader.parameterFileName;
	plantAge = loader.plantAge;
	plantSeed = loader.plantSeed;
	pattern = loader.pattern;
	patternBounds = loader.patternBounds;
	archimed1ConfigFileName = loader.archimed1ConfigFileName;
 
	List<SimRecord> simRecords = loader.simRecords;
 
	int numberOfSimulations = simRecords.size();
	(...)

The load () method will return a report. If l.succeeded () is false, the report can be shown to the user, it will contain a detailed error message.

Possible errors are:

  • a field expected by the loader could not be found in the file (missing in file)
  • a field in the file is unknown by the loader (missing in loader)
  • a field has a wrong type (e.g. expected int, found double)
  • a check failed (e.g. plantAge is supposed to be > 0)

It is possible to add checks by overriding the checks () method. It is possible to check simple assertions like in the example above. It is also possible to make more complicated checks like checking if the number of rows in the list is greater than 0. In case of trouble in checks (), write an error message with report (message) and throw an exception to stop the process.

After loading the file, all fields can be retrieved directly, they are all public fields. It is also possible to add and call a method in the fileLoader to change all these parameters into another data structure, e.g. a list of trees in a forest stand or a predefined parameter object.

Finally, it is possible to call the FileLoader toString () method after the process to check what happened. Here are two examples after a successful and after a failed loading :

FileLoader       : ScriptRaphael2013FileLoader
loaded file      : /home/coligny/workspace/amapstudio/data/simeo/edito/principesRaphael/wd1/principesCmd1.txt
loader report    : Le fichier a été chargé correctement
loading succeeded: true

-- Loaded data --
parameterFileName = PhoenixRomana.txt
plantAge = 200
plantSeed = 1
archimed1ConfigFileName = archimed1.config
pattern = ((0,10);(10,0))
patternBounds = ((-5,-5);(15,15))
simRecords: 
sim1	PinnaeDistance_1(2D;1;(0:2.3);(50:10);(100:2))
sim2	PinnaeDistance_1(2D;1;(0:6);(50:15);(100:4))
-- end-of-loaded data --
FileLoader       : ScriptRaphael2013FileLoader
loaded file      : /home/coligny/workspace/amapstudio/data/simeo/edito/principesRaphael/wd1/principesCmd1.txt
loader report    : The simRecords list should not be empty
loading succeeded: false
private/filereader.1386767359.txt.gz · Last modified: 2021/12/15 15:38 (external edit)