The fo_open command is used to open a file for writing to. It takes two arguments the first is a variable which after the call will be set to a value if the file was opened or 0 if it wasn't opened, the variable holds the file id and is then used on all functions relating to the opened file. The second argument is the file name. To open an output file called “Helloworld.txt” use the following line of code.
fo_open FileId “HelloWorld.txt”
Before writing to the file in the example above you should check that FileOpen is not set to 0.
The fo_open will over write an existing file if you want to append to an existing file then use the fo_openapp command this takes the same arguments as the fo_open command.
You can check that a file is open using the fo_isopen command which takes a two arguments, the first will be set to true if the file is open and the second is the file id of the file to be checked if its opened.
To close the output file the fo_close is used this takes a single argument which is the file id of the file to close.
The fi_open command is used to open a file for reading to. It takes two arguments the first is a variable which after the call will be set to the file id if the file was opened or 0 if it wasn't opened. The second argument is the file name.
You can check that a file is open using the fi_isopen command which takes a two arguments, the first will be set to true if the file is open and the second is the file id of the file to be checked if its opened.
To close the output file the fi_close is used this takes a single argument which is the file id of the file to close.
Binary files allow you to write data in the raw format used by evolve to store variables it will produce files that are not necessarily user readable but which are compact.
To write binary data to a file the fo_write command is used. This takes a two or more arguments the first is the File Id followed by the value(s). Strings are written as a series of null terminated characters.
The following code shows how to write some binary data to a file.
Name = “Fred”
Numeric = 0.25
fi_write FileId Name Numeric
To read data from a binary file use either the fi_read command or the fi_readbyte command. The fi_read command reads the number of bytes for the passed data type, with strings it will add characters until it reaches a null byte or the end of file. When using the fi_read command the variables must have been predefined so that evolve can work out how to load the values.
So to read the data written in the previous example you could use
Name = “”
Numeric = 0.0
fi_read FileId Name Numeric
To read individual bytes of a binary or text file the fi_readbyte command can be used.
While reading the data the fi_eof can be used to determine if the end of file has been reached.
The following example demonstrates reading and writing binary files.
//---------------------------------------
// File: BinaryFile.e
//---------------------------------------
//---------------------------------------
// Block: WriteFile
//---------------------------------------
// Variables:
// Success
//---------------------------------------
block WriteFile Success
//open an output file
fo_open FileId "BinaryFile.bin"
//check file is open
if FileId == 0
outl "Cant open output file"
Success = false
exit_program
_if
//define some variables
ByteVal = 0x03
IntVal = 123
FloatVal = 1.23
BoolVal = false
StrVal = "String"
//write variables to file
fo_write FileId ByteVal
fo_write FileId IntVal
fo_write FileId FloatVal
//can put multiple writes on a line
fo_write FileId BoolVal StrVal
//close the file
fo_close FileId
Success = true
_block
//---------------------------------------
// Block: ReadFile
//---------------------------------------
block ReadFile
//open an input file
fi_open FileId "BinaryFile.bin"
//check file is open
if FileId == 0
outl "Cant open input file"
exit_program
_if
//define some variables
ByteVal = 0x0
IntVal = 0
FloatVal = 0.0
BoolVal = true
StrVal = ""
//read variables from file
fi_read FileId ByteVal
fi_read FileId IntVal
fi_read FileId FloatVal
//can put multiple reads on a line
fi_read FileId BoolVal StrVal
//display the data on the screen
outl ByteVal ", " IntVal ", " FloatVal ", " StrVal
//close the file
fi_close FileId
_block
//---------------------------------------
// Block: go
//---------------------------------------
block Go
Ok = false
WriteFile Ok
//check file was written on
if Ok == true
ReadFile
_if
_block
If you want to read multiple bytes at a time they can be read into a byte list using the fi_readbyte command this allows you to specify the number of bytes to read and will adjust the byte list size to match.
//---------------------------------------
// File: ReadBytes.e
//---------------------------------------
//---------------------------------------
// Block: Go
//---------------------------------------
block Go
//open the file
fo_open FileId "C:\Users\Kevin\Documents\deleteme1.txt"
if FileId == 0
outl "Can't open output file"
exit_program
_if
//write some data
Var1 = { 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' }
fo_write FileId Var1
fo_close FileId
//open an input file
fi_open FileId "C:\Users\Kevin\Documents\deleteme1.txt"
if FileId == false
outl "Can't open input file"
exit_program
_if
//read 3 bytes
fi_readbytes FileId Var2 3
outl Var2[0] "," Var2[1] "," Var2[2] ","
//get the list size
lst_size Size Var2
outl "ListSize:" Size
//read 6 more bytes
fi_readbytes FileId Var2 6
outl Var2[0] "," Var2[1] "," Var2[2] "," Var2[3] "," Var2[4] "," Var2[5]
//get the list size
lst_size Size Var2
outl "ListSize:" Size
//close the file
fi_close FileId
_block
Text files are opened with the same commands as binary files but different commands are used to write the data. Text files produce files that are human readable so for example if your code used the following to write to the file
Name = “Fred”
Numeric = 0.25
fo_writetxt FileId Name Numeric
Then if you opened the file you would see
Fred0.25
Text file are written with the fo_writetxt and fo_writetxtl commands these take the file id followed by a single or multiple arguments, if the argument is a numeric variable of value then it will be converted into a string version. Using the fo_writetxtl command will add a carraige return at the end of the file, with both of these commands the strings are not null terminated.
Text files can be read with the fi_readbyte command or the fi_readtxt. The fi_readtxt command takes three arguments the first is the file Id the second is variable to write the string into and the third is a termination byte, data will be read until a matching bye is found.
//---------------------------------------
// File: TextFile.e
//---------------------------------------
//---------------------------------------
// Block: WriteFile
//---------------------------------------
// Variables:
// Success
//---------------------------------------
block WriteFile Success
//open an output file
fo_open FileId "TextFile.txt"
//check file is open
if FileId == 0
outl "Cant open output file"
Success = false
exit_program
_if
//define some variables
ByteVal = 0x03
IntVal = 123
FloatVal = 1.23
BoolVal = false
StrVal = "String"
//write variables to file
fo_writetxt FileId ByteVal
fo_writetxt FileId ", "
fo_writetxtl FileId IntVal
fo_writetxtl FileId FloatVal
//can put multiple writes on a line
fo_writetxtl FileId BoolVal ", " StrVal
//close the files
fo_close FileId
Success = true
_block
//---------------------------------------
// Block: ReadFile
//---------------------------------------
block ReadFile
//open an input file
fi_open FileId "TextFile.txt"
//check file is open
if FileId == 0
outl "Cant open input file"
exit_program
_if
Eof = false
//Read until reached the end of file
while Eof == false
//read line of text up to the carriage return
fi_readtxt FileId StrInput '\r'
//display the data on the screen
outl StrInput
//check for end of file
fi_eof FileId Eof
_while
//close the file
fi_close FileId
_block
//---------------------------------------
// Block: go
//---------------------------------------
block Go
Ok = false
WriteFile Ok
//check file was written
if Ok == true
//read the file back
ReadFile
_if
_block
The file id was briefly mentioned previously this allows working on multiple files at the same time the followinf example opens 5 files writes some text to them, it then closes the files and reopens them to display the contents of each file.
//---------------------------------------
// File: MultipleFiles.e
//---------------------------------------
//---------------------------------------
// Block: OpenOutFile
//---------------------------------------
// Variables:
// FileId - List to save the file id in
// I - Index into list to save the file
// FileName - Name of the file to open
//---------------------------------------
block OpenOutFile FileId I FileName
//open an output file
fo_open FileId[I] FileName
//check file is open
if FileId[I] == 0
outl "Cant open output file:" FileName
Success = false
exit_program
_if
_block
//---------------------------------------
// Block: OpenInFile
//---------------------------------------
// Variables:
// FileId - List to save the file id in
// I - Index into list to save the file
// FileName - Name of the file to open
//---------------------------------------
block OpenInFile FileId I FileName
//open an output file
fi_open FileId[I] FileName
//check file is open
if FileId[I] == 0
outl "Cant open input file:" FileName
Success = false
exit_program
_if
_block
//---------------------------------------
// Block: Go
//---------------------------------------
block Go
FileIds[5] = 0
I = 0
// open some files
loop I 5
FileName = "File"
str_add FileName I
str_add FileName ".txt"
OpenOutFile FileIds I FileName
_loop
//write some data into each file and close
loop I 5
fo_writetxt FileIds[I] I "TestFile"
fo_close FileIds[I]
_loop
//open some input files
loop I 5
FileName = "File"
str_add FileName I
str_add FileName ".txt"
OpenInFile FileIds I FileName
_loop
//Display the contents
loop I 5
fi_read FileIds[I] FileData
outl FileData
_loop
loop I 5
fi_close FileIds[I]
_loop
_block
Evolve has built in support for loading and saving files in .csv format. CSV stands for comma separated variables this type of file is useful as most databases and spread sheets can write files in csv format. CSV files contain records of one or more field on a line, the fields are seperated by a comma and there is one record on the line. So for example a CSV file of an address book might consist of the following.
Ronnie,Dio,01246849
Gary,Moore,87173864
To save data as a CSV file it needs to be stored in a container with each variable being a list of the same size. The command filecsv_out is used to write the csv file it takes three arguments the first is a variable which is set to true or false depending on whether the file write was successful, the second is the container with the data to be written and the third is the file name.
To load a CSV file a container must be created with the correct number of fields, the length of the field lists will be set automatically when the file is loaded. The command fcsv_in is used to read the csv file it takes three arguments the first is a variable which is set to true or false depending on whether the file read was successful, the second is the container to read the data into and the third is the file name.
//---------------------------------------
// File: CSVFile.e
//---------------------------------------
//---------------------------------------
// Block: DisplayData
//---------------------------------------
// Variables:
// Data
//---------------------------------------
block DisplayData @Data
I = 0
while I < 100
outl Data_Value1[I] " " Data_Value2[I] " " Data_Result[I]
++ I
_while
_block
//---------------------------------------
// Block: go
//---------------------------------------
block Go
I = 0
//create some records
while I < 100
Record.Value1[I] = I
Record.Value2[I] = I * 2
Record.Result[I] = Record_Value1[I] + Record_Value2[I]
++ I
_while
//display the record
DisplayData @Record
//save the file
fcsv_out FileSaved @Record "CSVFile.csv"
if FileSaved == false
outl "Can't save the file"
exit_program
_if
NewRecord.Value1 = 0
NewRecord.Value2 = 0
NewRecord.Result = 0
//load the file
fcsv_in FileSaved @NewRecord "CSVFile.csv"
//display the loaded records
DisplayData @NewRecord
_block
It is often necessary to know the size and when a file was updated this can be done with the f_details command. It takes two arguments a container to return the results in and the filename.
The following is an example of it in use upon success the container will return the following fields
Hour, Min, Sec, Day, Mon, Yr and Size.
//---------------------------------------
// File: FileDetails.e
//---------------------------------------
//---------------------------------------
// Block: WriteFile
//---------------------------------------
// Variables:
// Success
//---------------------------------------
block WriteFile Success
//open an output file
fo_open FileId "TextFile.txt"
//check file is open
if FileId == 0
outl "Cant open output file"
Success = false
exit_program
_if
//Write some data
fo_writetxt FileId "Test"
//close the files
fo_close FileId
Success = true
_block
//---------------------------------------
// Block: go
//---------------------------------------
block Go
Ok = false
WriteFile Ok
//check file was written
if Ok == true
//read the file back
f_details @Details "TextFile.txt"
outl "Time: " Details.Hour ":" Details.Min ":" Details.Sec
outl "Date: " Details.Day ":" Details.Mon ":" Details.Yr
outl "Size: " Details.Size
_if
_block
When using files being able to split up the filename and path into the separate pieces from a string can be done using the f_splitname function. This takes a container and the filename as arguments and returns a container containing Path, Name and Ext.
The f_chgext command can be used to change the extension on a filename this takes a container as the first argument followed by the filename to change and finally the new extension.
//---------------------------------------
// File: FileNameFuncs.e
//---------------------------------------
//---------------------------------------
// Block: Go
//---------------------------------------
block Go
//f_splitname
f_splitname @Result "c:\testdir\testfile.txt"
outl "Path: " Result.Path
outl "Name: " Result.Name
outl "Extension: " Result.Ext
new_line
//f_chgext
f_chgext NewName "test.c" "e"
outl "File Name: " NewName
_block