Loading Files#
When things are completely done in code, they will be harder to change down the line. Sometimes they are also very hard to create in code alone in the first place. This is, why we already know about loading images, sounds and fonts. What if we wanted to load other things dynamically, too?
What is a File?#
Generally speaking, a file is a bunch of data that is stored somewhere on some kind of storage medium in a file system. "A bunch of data" could be a few bytes, but it could also be billions of bytes or more. "some kind of storage medium" could be a thumbdrive or storage card, but most commonly this will be your hard drive. "A file system" is something that organizes that storage medium for you, usually in a way that gives you paths and filenames.
Absolute and Relative Paths#
When you want to access a file from a program, you will need its path. This is the same meaning of "path" that we discussed early in this course and it can come in two flavors:
- The absolute path: this is a path that includes everything, starting from the root of your storage system. Those can look like this:
C:\Users\bernd\Downloads\slides.pdf
(Windows)/Users/bernd/Downloads/slides.pdf
(MacOS)/home/bernd/Downloads/slides.pdf
(Linux) they are all independent of your current working directory.
- The relative path instead depends on your current working directory. If your program runs in
C:\Program Files\Game\
right now1, then a relative path will start at that exact spot. A relative path would look like one of these:slides.pdf
(just the name)extra-files/slides.pdf
(a file in a sub-directory of the current working directory, MacOS or Linux)extra-files\slides.pdf
(a file in a sub-directory of the current working directory, Windows)..\somewhere-else\slides.pdf
(..
means "go one directory up)
Relative, Most of the Time
Most of the time, you will probably be working with relative paths. In Processing, your files will be loaded from a data
directory in your sketch folder. Relative paths begin in that data folder.
Reading#
With the path and filename, we can now try to access a file and read it. Processing has a helpful thing for us: the loadStrings()
function. It does quite a few common things at once: It opens a file for reading, reads everything that's in the file and splits it into an Array of Strings. Each line in the file goes into one element of the array. It is also very forgiving in case of errors.
String[] lines = loadStrings("demo.txt");
println(lines[1]); // would print "bbb"
Examples in the example repository
Since these examples are all made up of several files, you will find them in the examples repository for easier access.
Possible Errors
There are many things that could go wrong while opening a file.
- There might not be a file at that name - maybe because you mistyped, or maybe because the file was deleted.
- You might not be allowed to open that file. Computers keep track of "ownership" and "access control" and not everyone is allowed to read and write everything.
- A hardware failure might prevent you from accessing a file.
loadStrings()
handles all of these for you and just prints an error message to the console. In other programming languages, you'd have to handle errors like these yourself!
As a more realistic example, let's have a list of names and let's pick one name randomly:
String[] lines;
String chosenLine;
void setup() {
size(500, 500);
lines = loadStrings("names.txt");
int namecount = lines.length;
int randomIndex = floor(random(0, namecount));
chosenLine = lines[randomIndex];
}
void draw() {
background(0);
textAlign(CENTER, CENTER);
float size = sin((float) millis() / 1000) * 25 + 50;
textSize(size);
text(chosenLine, width / 2, height / 2);
}
The marked section loads the file, and then selects a random line from that file. All the rest is just fancy rendering. Whenever you start this sketch, it will spit out a random name from that file. Even better: the file can be changed independently from your program.
How Is Data Stored?#
In these examples, we used .txt
files, which are also often called "plain text" files. These files can't contain any fancy formatting, they just contain text. They are usually encoded in UTF-8 or ASCII, but they could be in any encoding. You can open and alter .txt
files with pretty much any text editor in the world.
If you put the text "Hello, World" into a plain text file, it will be stored as 12 bytes representing (for this chosen example it is exactly 1 byte per character) and the bytes on your disk will be the ASCII or UTF-8 encoded representation of this text. You can also refer to an ASCII-Table for this:
Letter: H e l l o , W o r l d
Decimal: 72 101 108 108 111 44 32 87 111 114 108 100
Hex: 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64
Allowed Contents in Files Like These#
Here is the fun part: It's your program, it's (usually) your computer. You make the rules. As long as you can work with the file contents, it's all fine.
loadStrings()
is best used for text or text-like information, but even that is extremely powerful. It is totally OK to come up with your own file format that might contain information about your game (levels, high score, savegames).
Above we made the very arbitrary decision to have "one name on each line", and we wrote our program in a way that it only displayed a single line randomly. Those two fit together, and that's all it takes.
For more complicated data, it is often good to stick to an existing, established format. Let's look at a few very common ways to store structured data in text-based formats next!
-
It is possible (and pretty common) to change the current working directory of a running program. ↩