0Pricing
Lua Academy · Lesson

Opening Files with io.open

Open files in read, write, and append modes using io.open.

Opening Files with io.open is a free Lua Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

io.open Syntax

io.open(filename, mode) opens a file and returns a file handle, or nil plus an error message on failure. Mode strings: "r" read (default), "w" write (truncate), "a" append, "r+" read/write, "b" suffix for binary.

local f, err = io.open("test.txt", "w")
if not f then
  print("Error:", err)
  return
end
f:write("Hello, Lua!\n")
f:close()
print("Written successfully")

Read Mode

Open in "r" mode to read an existing file. Always check for nil — if the file doesn't exist, io.open returns nil and an error message. Never assume the file is there.

local f, err = io.open("test.txt", "r")
if not f then
  print("Cannot open:", err)
  return
end
local content = f:read("*a")  -- read all
f:close()
print(content)

Write and Append Modes

"w" creates or truncates the file. "a" creates the file if needed and always appends to the end. Use append mode for log files where you don't want to lose previous content.

-- Write (creates/truncates)
local f = io.open("log.txt", "w")
f:write("Session started\n")
f:close()

-- Append (adds to end)
local g = io.open("log.txt", "a")
g:write("Event: login\n")
g:write("Event: action\n")
g:close()

Binary Mode

Append "b" to any mode for binary reading/writing. On Unix, text and binary modes are identical. On Windows, text mode translates \n to \r\n; binary mode disables this. Always use binary mode for non-text files.

-- Binary read
local f = io.open("image.png", "rb")
if f then
  local header = f:read(8)   -- read 8 bytes
  f:close()
  -- Check PNG magic number: \137PNG\r\n\26\n
  print("Read", #header, "bytes")
end

-- Binary write
local g = io.open("out.bin", "wb")
if g then
  g:write(string.char(0x89, 0x50, 0x4E, 0x47))
  g:close()
end

File Handle Methods

A file handle (returned by io.open) has methods: f:read(...), f:write(...), f:lines(), f:seek(whence, offset), f:flush(), f:close(). Call them with colon syntax on the handle.

local f = io.open("data.txt", "w")
f:write("line 1\n")
f:write("line 2\n")
f:write("line 3\n")
f:flush()   -- force write to disk
f:close()

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

io.input and io.output

io.input(f) sets the default input file; io.output(f) sets the default output. io.read() reads from the current input; io.write() writes to current output. Default input is stdin; default output is stdout.

-- Read from stdin (default input)
local line = io.read()  -- reads one line
print("You entered:", line)

-- Set default output to a file
io.output("out.txt")
io.write("This goes to out.txt\n")
io.output(io.stdout)  -- restore stdout

Checking File Existence

Lua has no file.exists(), but you can use io.open in read mode — if it fails, the file doesn't exist (or is inaccessible). Alternatively, on POSIX systems use os.execute or the lfs library.

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

print(fileExists("test.txt"))     -- true/false
print(fileExists("noexist.txt"))  -- false

Reading with Modes

f:read() accepts format strings: "l" or "*l" reads one line (strips newline); "L" keeps newline; "n" reads a number; "a" or "*a" reads to EOF; a number reads that many bytes.

local f = io.open("data.txt", "r")
if f then
  local line1 = f:read("l")   -- first line, no newline
  local num   = f:read("n")   -- next number in file
  local rest  = f:read("a")   -- rest of file
  f:close()
  print(type(line1), type(num))
end

Temporary Files

io.tmpfile() opens a temporary file in read/write mode. The file is automatically deleted when the program exits or the handle is garbage collected. Use for intermediate processing without managing filenames.

local tmp = io.tmpfile()
tmp:write("temporary data\n")
tmp:write("more data\n")

-- Seek back to start and read
tmp:seek("set", 0)
local content = tmp:read("a")
print(content)
-- File auto-deleted when tmp is collected

Iterating Lines with lines()

f:lines() returns an iterator that reads one line at a time. It automatically closes the file when the iterator is exhausted. This is memory-efficient for large files — it never loads the whole file at once.

local function countLines(path)
  local count = 0
  local f, err = io.open(path, "r")
  if not f then return nil, err end
  for _ in f:lines() do
    count = count + 1
  end
  -- f is closed automatically by lines()
  return count
end

local n, err = countLines("data.txt")
print("Lines:", n)

Quick Check

What does io.open("file.txt", "a") do if the file does not exist?

Recap: io.open

Summary:

  • io.open(path, mode) returns handle or nil+error
  • Modes: r w a r+ b
  • Always check for nil before using the handle
  • Call f:close() when done
  • f:lines() for memory-efficient line iteration
  • io.tmpfile() for auto-deleted temp files

Frequently asked questions

Is the “Opening Files with io.open” lesson free?

Yes — the full text of “Opening Files with io.open” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.

What will I learn in “Opening Files with io.open”?

Open files in read, write, and append modes using io.open. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Opening Files with io.open” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Opening Files with io.open
  2. Reading File Contents
  3. Writing and Appending to Files
  4. Closing Files and Error Handling
← Back to Lua Academy