= Programming 101 input and output

:Author: Seth Kenlon
:License: Creative Commons Attribution-ShareAlike

Some data is ephemeral, stored in RAM and only significant while an application is running.
Some data, however, is meant to be persistent, stored on a hard drive for later use.
When you program, whether you're working on a simple script or a complex suite of tools, it's common to need to read and write files.
Sometimes a file may contain configuration options, and other times the file is the data that your user is creating with your application.
Every language handles this task a little differently, and this article demonstrates how to handle data files with Lua.

== Install Lua

If you're on Linux, you can install Lua from your distribution's software repository.
On macOS, you can install Lua from https://opensource.com/article/20/11/macports[MacPorts] or https://opensource.com/article/20/6/homebrew-mac[Homebrew].
On Windows, you can install Lua from https://opensource.com/article/20/3/chocolatey[Chocolatey].

Once you have Lua installed, open your favorite text editor and get ready to code.

== Reading a file with Lua

Lua uses the `io` library for data input and output.
In this example, I create a function called `ingest` to read data in from a file, and then I parse it with the `:read` function.
When opening a file in Lua, there are several modes you can enable.
Because I only need to read data from this file, I use the `r` (for "read") mode.

[source,lua]
----
function ingest(file)
   local f = io.open(file, "r")
   local lines = f:read("*all")
   f:close()
   return(lines)
end

myfile=ingest("example.txt")
print(myfile)
----

In my code, notice that the variable `myfile` is created as a way to trigger the `ingest` function, and is therefore the recipient of whatever that function returns.
The `ingest` function returns the lines (from a variable intuitively called `lines`) of the file.
When the contents of the `myfile` variable is printed as the final step of this code, the lines of the file appear in your terminal.

If the file `example.txt` contained configuration options, then I would write some additional code to parse that data, probably using another Lua library, depending on whether the configuration was stored as an INI file or YAML file or some other format.
If the data was an SVG graphic, then I'd write extra code to parse XML, probably using an SVG library for Lua.
In other words, the data your code reads can be manipulated once it's loaded into memory, but all that's required to load it is the `io` library.

== Writing data to a file with Lua

Whether you're storing data that your user has created with your application, or just metadata about what a user has done in an application (for instance, game saves or recent songs played), there are lots of good reasons to want to store data for later use.
In Lua, this is achieved through the `io` library, this time by opening a file writing data into it, and then closing the file.

[source,lua]
----
function exgest(file)
   local f = io.open(file, "a")
   io.output(f)
   io.write("hello world\n")
   io.close(f)
end

exgest("example.txt")
----

When I read data from the file, I opened the file in `r` mode, but this time I use `a` (for "append") to write data to the end of the file.
Because I'm writing plain text into a file, I added my own newline character (`\n`).
Often you're not writing raw text into a file, though, and you'll probably use an additional library to write a specific format instead.
For instance, you might use an INI or YAML library to help write configuration files, an XML library to write XML, and so on.

== File modes

When opening files in Lua, there are some safeguards and parameters to define how a file should be handled.
The default is `r`, which permits you only to read data.

* `r` read only
* `w` overwrite, or create a new file if it doesn't already exist
* `r+` read and overwrite
* `a` append data to a file, or make a new file if it doesn't already exist
* `a+` read data, append data to a file, or make a new file if it doesn't already exist

There are a few others (`b` for binary formats, for instance) but those are the most common.
For full documentation, refer to the http://lua.org/manual[excellent Lua documentation on Lua.org/manual].
