Gw Temp

Menu

Tutorial - 'File Input/Output' by rjt

An item about Sphere posted on

Blurb

This tutorial explains how to read from and write to files in Sphere

Body

This tutorial covers file input/output (reading from, and writing to files) in Sphere. This is required if you want to make saving systems and other things that involve recording information like this. This tutorial is aimed at people that understand the basics of Sphere.

There are two types of files that Sphere has code to create: ‘Save’ files, which store information using keys, and raw files, which writes using byte arrays. Save files are the more common type, and if you aren’t very advanced in Sphere you may not want to read the section on raw files, as you probably won’t need it (yet). This tutorial shows how to create, read from and write to these files.

Save Files
As I said before, these store information in keys. What I did not do, was explain exactly what a key is, so I will go ahead and do that now: keys are a way of indexing (organizing) data, and it uses the format key=value. For example, if I had a key called health that stored a character’s health score in your game, it would look like this (when the file was opened in a text editor): health=100.

However, before a file can have a value read from or written to, it must be saved into a variable. This can be done like so:

var File = OpenFile(“File.txt”);

In English: Create the variable File and give it the value of the text file ‘File.txt’. If this file does not exist it will be created. Sphere looks for this file in the /save/ folder inside your game’s folder; and creates it there if it does not exist. If you want it to be opened from your game’s folder, and not in /save/, use the filename “../File.txt” (or “../scripts/File.txt” if you want it opened from your scripts folder).

The code to write the text ‘hi’ to the key ‘message’ in a file called ‘File.txt’ is:

var File = OpenFile(“File.txt”);
File.write(“message”, “hi”);
If the key ‘message’ does not exist, it will be created. Reading from a key is just as easy:
var ValueReadFromFile = File.read(“message”, “message does not exist”);
The second parameter (“message does not exist”) is the default value, which is used if the key ‘message’ (which is the first parameter) does not exist in the file. The default value also determines what type of variable will be read from ‘message’ (if the default value is a string a string will be read, if it is a number, a number will be read; if the value read is not the type it should be (for example if the default value is a number and the value read is not a number) then the default value will be used). If you put this code after the code which writes to a file (above), the variable ValueReadFromFile will get the value ‘hi’ from the key ‘message’.
The file will not be saved until the file object (in this case the variable File) is destroyed. To save a file before this happens, you can use File.flush(). To see this:
function game()
{
File=OpenFile("TextFile.txt");
File.write("message", "This will not be written");
while(1){}
}
This will loop forever, and so the file object will never be destroyed, which means that TextFile.txt will never be written to. You can test this by running the program, killing it (using Alt+F4 in Windows), and then checking if /save/TextFile.txt exists (it won’t). If you add the line File.flush(); before the while loop, the file will be created and saved (you will have to kill the program again). When you check /save/ you will find TextFile.txt has been created.

Raw Files

Raw files are written to and read from using Byte Arrays. Byte arrays are groups of bytes. For those of you unfamiliar with bytes, a byte can hold one character (for example: a letter, one numerical digit or a formatting character like a space or a new line). Byte arrays hold these characters in their numerical value (their value in numbers). To turn a string of text into a byte array, the function CreateByteArrayFromString(String) is used. Likewise, to create a string from a byte array, CreateStringFromByteArray(ByteArray) is used. Because byte arrays are arrays, you can access single elements of the array like so:
var ByteArray = CreateByteArrayFromString(“Hello World!”);
GetSystemFont().drawText(1,1,ByteArray[0]);
FlipScreen();
GetKey();
The [0] selects the first value in the array (1 would be the second, 2 the third ect.). Because this is a byte array, the value of ByteArray[0] will be a number (H’s numerical value, which is 72). Anyway, this isn’t very important, if you understand it then well and good, but if you’re having difficulties understanding byte array’s don’t worry as it isn’t that important. Just understand how to make a byte array from a string, and how to make a string from a byte array. Here is some code that opens a raw file and writes to it (raw files are saved in the /other/ directory in your game’s folder, so look there for rawfile.txt after you have ran the code):
function game()
{
var message = “Hello, this is text that will be written to a raw file”;
var ByteArray = CreateByteArrayFromString(message);
var RawFile = OpenRawFile(“rawfile.txt”, true);
RawFile.write(ByteArray);
RawFile.close();
}

The third and fourth lines create a string that is then turned into a byte array. The fifth opens rawfile.txt (the ‘true’ means that the file is going to be opened and written to, or if the file does not exist, be created and written to; if this was ‘false’, then the file would be opened to be read from, or return an error if the file did not exist). When a raw file is opened to be written to, whatever was in the file before will be deleted. The sixth line writes the byte array to the file, and then the seventh closes it (the file).

You read from a raw file like so:
RawFile.read(NumberOfCharactersToRead);
Another example (replace your function game() from the last example with this one):
function game()
{
RawFile = OpenRawFile("rawfile.txt", false);
var ReadFromFile = CreateStringFromByteArray(RawFile.read(2));
GetSystemFont().drawText(1,1, ReadFromFile);
FlipScreen();
GetKey();
}
Note the ‘false’ in line number 3, indicating the file will be opened and read from. Line number four reads two bytes from the start of rawfile.txt, turns the bytes into a string, and creates a variable to put the string in. This variable is then shown on screen on line 5. Because the first two letters in rawfile.txt are ‘He’, that is the value read and put on screen. When you are reading from or writing to a file, there is a position in the file that you are currently at. So when you open a file you are at position 0 in this file (the start of it), and if you write three letters (say ‘Hey’)to the file, your position will become place 3 (and position 0 now has the value of the letter ‘H’, 1 has the value of ‘e’ ect.). If you want to change your position in a file, the function RawFile.setPosition(NewPosition) is used. If you set your position back to 0, and write another three letters, ‘Hey’ will be replaced with the new letters. To find what position you are in the file already, RawFile.getPosition() is used. RawFile.getSize() tells you the number of bytes in RawFile.

I said earlier that when you write to a raw file, it’s previous contents get deleted. If you want to edit a file instead, then you should read the contents of a file into a variable, turn it into a string and edit this, then return it to a byte array and write back to the file. If you wanted to add one byte array to the end of another, the function concat is used. concat is used like so:
NewByteArray = OldByteArray + OldByteArray.concat(ByteArrayToBeAdded)
In this example, NewByteArray gets the value of OldByteArray with ByteArrayToBeAdded added on to the end of it. Here is an example of reading from a file, editing its contents, and adding to the end of it (editing the message we have in rawfile.txt):
function game()
{
var RawFile = OpenRawFile("rawfile.txt", false);
var FileSize = RawFile.getSize();
var ReadFromFile = RawFile.read(FileSize);
RawFile.close();
ReadFromFile[0] = CreateByteArrayFromString("'")[0];
var message = CreateByteArrayFromString("This will be added to the end of the raw file");
ReadFromFile = ReadFromFile.concat(message);
RawFile = OpenRawFile("rawfile.txt", true);
RawFile.write(ReadFromFile);
RawFile.close();
}
Lines three to five open rawfile.txt, find it’s size, and read it’s contents into the variable ReadFromFile (line 5 reads the amount of bytes equal to the file size of the file, meaning that it reads all of the bytes in the file). Line 7 sets the first value in the byte array ReadFromFile (ReadFromFile[0]) to the first value in the byte array message, which only contains one value, which is the numerical value of an apostrophe (‘). Line 8 creates a new byte array called message, and line 9 adds message to the end of ReadFromFile. . Line 11 writes the edited RawFile back to rawfile.txt.

That brings this tutorial to an end. If you have any questions or comments, email me at rjt[at]spheredev.net.