Reading Files in Lua

Reading and writing files are basic tasks needed for many Lua programs. First we’ll look at some examples of reading files.

-- Reading files requires checking most calls for errors.
-- This helper will streamline our error checks below.
local function check(e)
    if e then
        error(e)
    end
end

-- Perhaps the most basic file reading task is
-- slurping a file's entire contents into memory.
local file = io.open("/tmp/dat", "r")
check(file == nil and "Failed to open file" or nil)
local content = file:read("*all")
file:close()
print(content)

-- You'll often want more control over how and what
-- parts of a file are read. For these tasks, start
-- by opening a file to obtain a file handle.
file = io.open("/tmp/dat", "r")
check(file == nil and "Failed to open file" or nil)

-- Read some bytes from the beginning of the file.
-- Allow up to 5 to be read but also note how many
-- actually were read.
local b1 = file:read(5)
print(string.format("%d bytes: %s", #b1, b1))

-- You can also seek to a known location in the file
-- and read from there.
file:seek("set", 6)
local b2 = file:read(2)
print(string.format("%d bytes @ %d: %s", #b2, 6, b2))

-- Other methods of seeking are relative to the
-- current cursor position,
file:seek("cur", 4)

-- and relative to the end of the file.
file:seek("end", -10)

-- The io library provides some functions that may
-- be helpful for file reading. For example, reads
-- like the ones above can be more robustly
-- implemented with io.read.
file:seek("set", 6)
local b3 = file:read(2)
print(string.format("%d bytes @ %d: %s", #b3, 6, b3))

-- There is no built-in rewind, but
-- seek("set", 0) accomplishes this.
file:seek("set", 0)

-- Lua doesn't have a built-in buffered reader like Go's bufio,
-- but you can implement similar functionality using io.lines
-- for efficient reading of lines.
for line in io.lines("/tmp/dat") do
    print(line)
end

-- Close the file when you're done.
file:close()

To run this script:

$ echo "hello" > /tmp/dat
$ echo "lua" >>   /tmp/dat
$ lua reading-files.lua
hello
lua
5 bytes: hello
2 bytes @ 6: lu
2 bytes @ 6: lu
hello
lua

Next we’ll look at writing files.