Web Analytics

File I/O in Lua

Intermediate ~20 min read

File I/O (Input/Output) is essential for reading and writing data to files. Lua provides a simple yet powerful I/O library for working with files. In this lesson, you'll learn how to read from files, write to files, handle different file modes, and perform common file operations. Let's explore file I/O in Lua!

Opening Files

Use io.open() to open a file:

-- Open file for reading
local file, err = io.open("data.txt", "r")

if not file then
    print("Error:", err)
else
    -- Use file
    file:close()
end

File Modes

Mode Description
"r" Read mode (default)
"w" Write mode (overwrites existing file)
"a" Append mode (adds to end of file)
"r+" Read and write (file must exist)
"w+" Read and write (overwrites)
"a+" Read and append
"rb", "wb" Binary mode
Output
Click Run to execute your code

Reading Files

Read Entire File

local file = io.open("data.txt", "r")
if file then
    local content = file:read("*all")
    print(content)
    file:close()
end

Read Line by Line

local file = io.open("data.txt", "r")
if file then
    for line in file:lines() do
        print(line)
    end
    file:close()
end

Read Modes

Mode Description
"*all" Read entire file
"*line" Read next line (default)
"*number" Read a number
n Read n characters
local file = io.open("data.txt", "r")
if file then
    -- Read 10 characters
    local chunk = file:read(10)
    
    -- Read a number
    local num = file:read("*number")
    
    -- Read a line
    local line = file:read("*line")
    
    file:close()
end
Output
Click Run to execute your code

Writing Files

Write to File

local file = io.open("output.txt", "w")
if file then
    file:write("Hello, World!\n")
    file:write("Line 2\n")
    file:write("Line 3\n")
    file:close()
end

Append to File

local file = io.open("output.txt", "a")
if file then
    file:write("Appended line\n")
    file:close()
end

Write Multiple Values

local file = io.open("output.txt", "w")
if file then
    file:write("Name: ", "Alice", "\n")
    file:write("Age: ", tostring(25), "\n")
    file:close()
end

Simple I/O Model

Lua also provides a simple I/O model using default files:

-- Set input file
io.input("data.txt")
local content = io.read("*all")
io.close()

-- Set output file
io.output("output.txt")
io.write("Hello, World!\n")
io.close()

-- Read from stdin, write to stdout
local line = io.read()
io.write("You entered: ", line, "\n")
Output
Click Run to execute your code

Common File Operations

Check if File Exists

local function fileExists(filename)
    local file = io.open(filename, "r")
    if file then
        file:close()
        return true
    end
    return false
end

if fileExists("data.txt") then
    print("File exists")
end

Copy File

local function copyFile(source, dest)
    local input = io.open(source, "rb")
    if not input then
        return false, "Cannot open source file"
    end
    
    local output = io.open(dest, "wb")
    if not output then
        input:close()
        return false, "Cannot create destination file"
    end
    
    local content = input:read("*all")
    output:write(content)
    
    input:close()
    output:close()
    
    return true
end

copyFile("source.txt", "destination.txt")

Read CSV File

local function readCSV(filename)
    local file = io.open(filename, "r")
    if not file then
        return nil, "Cannot open file"
    end
    
    local rows = {}
    for line in file:lines() do
        local row = {}
        for value in line:gmatch("([^,]+)") do
            table.insert(row, value)
        end
        table.insert(rows, row)
    end
    
    file:close()
    return rows
end

local data = readCSV("data.csv")
for i, row in ipairs(data) do
    print(table.concat(row, " | "))
end
Output
Click Run to execute your code

File I/O Best Practices

Best Practices:
  • Always close files: Use file:close() when done
  • Check for errors: Always check if io.open() succeeded
  • Use binary mode for binary files: "rb", "wb"
  • Handle large files carefully: Read in chunks, not all at once
  • Use pcall() for file operations: Catch unexpected errors
  • Flush buffers when needed: file:flush()

Safe File Operations

local function safeReadFile(filename)
    local success, result = pcall(function()
        local file = assert(io.open(filename, "r"))
        local content = file:read("*all")
        file:close()
        return content
    end)
    
    if success then
        return result
    else
        return nil, result
    end
end

local content, err = safeReadFile("data.txt")
if not content then
    print("Error:", err)
else
    print("Content:", content)
end

Practice Exercise

Try these file I/O challenges:

Output
Click Run to execute your code

Summary

In this lesson, you learned:

  • Opening files with io.open()
  • Different file modes (r, w, a, r+, w+, a+)
  • Reading files (entire, line by line, chunks)
  • Writing and appending to files
  • Simple I/O model with default files
  • Common file operations (exists, copy, CSV)
  • File I/O best practices

What's Next?

You've learned file I/O! In the final lesson, we'll explore performance optimizationโ€”how to write fast, efficient Lua code and profile your applications. Let's finish strong! ๐Ÿš€