Skip to main content

File Input / Output

CAESES features allow you to read and write ASCII files.

Reading a File

Importing or reading a custom file can be done as follows:

FFile in("C:/tmp/profiles.dat")
in.openRead()

// assume a string with rows of values
// so that we split the string and put the
// single values into a list

fobjectlist data(in.readLine().split())

// get the float value from the string

double resultvalue(data.at(0).castTo(FString).toDouble())

// close the file

in.close()

You can also use loops to iterate through a file and to store values in lists.

convert the objects with castTo()

The object list can only hold objects of type FObject which is the parent type of all objects in CAESES. This makes it a generalized and flexible container for any type of object, such as integers, float numbers, strings, points, curves, etc. However, as soon as you access the list to get back your objects, you need to convert the objects to the initial type via the castTo() command. In the special case of strings from a file, there is an additional cast to a float number, toDouble().

Fast Reading of Double Values

There is a convenient command to read a list of double-precision float values from a file and store it in a double series for quick access (without the need of casting the values). The following command reads all double values from the file where characters are ignored:

doubleseries numbers( in.readDoubles() )

// get the first value

double resultvalue( numbers.at(0) )

// or use a loop

loop(numbers.getSize())
double rv(numbers.at($$i))
// ...
endloop

If you only want to read a specified number of double values per call, you can simply provide the number of values you want to receive:

doubleseries numbers( in.readDoubles(3) )

// get the values

double x( numbers.at(0) )
double y( numbers.at(1) )
double z( numbers.at(2) )

caution

The method readDoubles() always starts again where it has stopped during the last call.

Reset Reading Location

If you read lines or numbers from a file and you want to jump back to the beginning of the file, you can use the seek() command. It sets the reading location based on the specified characters count:

// read all values of the file

doubleseries numbers( in.readDoubles() )

// go back to the beginning of the first character in the file -
// note that the count starts with 0

in.seek(0)

Writing a File

In order to create and write a file, you can use the following snippet:

// open a file for writing

FFile out( "c:/tmp/results.dat" )
out.openWrite()

// write out the x-coordinate of point a

out.writeLine("value = " + a.getX().toString())
out.close()

Paths and Working Directories

In most situations you would need to read or write files into specific design directories which are not static e.g. during studies and optimizations. For this purpose, you can use some global commands to get the current design or result directory.

// set up string for current design directory
// adding the name of the feature

string workingDir(getDesignDir() + "/" + this.getName() + "/")

// create the path

mkpath(workingDir)
note

Note that this.getName() returns the name of the feature instance. Another useful command e.g. to read files from a result directory is getResultsDir().

tip

It is always recommended to use / instead of \ in paths.

Environment Variables

By entering the command env() into the console widget, you can see which environment variable exist within CAESES. These can be used in features, too. Here is an example:

string workingDir("$CAESESDIR" + "/" + this.getName() + "/")

// ...

The mkpath() command and FFile can handle such a string and will resolve it. In order to receive the resolved string of an environment variable, you can write the following:

string dir( resolveEnv("$CAESESDIR") )

echo("dir=" + dir)

String Formatting

Please see the feature section "Strings" for more information about how you can format strings, and how you convert numbers into strings and vice versa.

Example for File Input and Output

The following example shows a typical scenario:

An input file is generated and filled with user-defined values. Then, a process is started which writes out another ASCII file containing a result value. This value is then extracted again.

// set up string for current design directory adding the name of the feature
string workingDir(getDesignDir() + "/" + this.getName() + "/")
// create a new path
mkpath(workingDir)

// open a file for writing
FFile out(workingDir + "value.dat")
out.openWrite()
// write out the parameter value of myParam
out.writeLine("value="+myParam.toString())
out.close()

// now the external tool
process myProcess("myTool.exe")
myProcess.setWorkingDir(workingDir)
myProcess.setArguments([workingDir+"value.dat"])
myProcess.run()

// read the result
FFile in(workingDir+"results.dat")
in.openRead()
// split the string by at least 1 whitespaces using regular expressions,
// put single values into a list
fobjectlist data(in.readLine().splitByRegExp("\s+"))
double resultvalue(data.at(0).castTo(FString).toDouble())
// close the file
in.close()