Lua 从入门到精通 / 13 - 文件与 I/O / File & System I/O
文件与 I/O / File & System I/O
Lua 的 I/O 库提供两种模式:简单模式(使用隐式文件句柄)和完全模式(使用显式文件句柄)。生产环境推荐完全模式。
Lua’s I/O library offers two modes: simple (implicit handle) and complete (explicit handle). Production code should use the complete mode.
🟢 基础 / Basics
1. 读写文件 / Reading & Writing Files
-- 写文件
local file = io.open("test.txt", "w")
file:write("Hello, Lua!\n")
file:write("Line 2\n")
file:close()
-- 读取整个文件
local file = io.open("test.txt", "r")
local content = file:read("*a") -- *a = 全部内容
file:close()
print(content)
-- 逐行读取
local file = io.open("test.txt", "r")
for line in file:lines() do
print(line)
end
file:close()
2. 文件模式 / File Modes
-- "r" 只读(默认)/ read
-- "w" 只写(覆盖)/ write (truncate)
-- "a" 追加 / append
-- "r+" 读写 / read + write
-- "w+" 读写(覆盖)/ read + write (truncate)
-- "a+" 读写(追加)/ read + write (append)
-- "rb" 二进制读 / binary read
-- "wb" 二进制写 / binary write
3. read() 的格式 / read() Formats
local file = io.open("data.txt", "r")
file:read("*n") -- 读取一个数字
file:read("*a") -- 读取整个文件
file:read("*l") -- 读取一行(默认,不含换行符)
file:read("*L") -- 读取一行(含换行符)
file:read(10) -- 读取 10 个字节
-- 读取多个值
local name, age = file:read("*l", "*n")
4. 标准 I/O / Standard I/O
-- io.input / io.output 设置默认输入/输出文件
io.input("input.txt")
io.output("output.txt")
-- 简单模式(使用隐式文件句柄)
io.write("Hello!\n")
local line = io.read("*l")
-- io.write vs print
io.write("a", "b", "c") -- abc(无空格无换行)
print("a", "b", "c") -- a b c(有 tab 和换行)
🟡 进阶 / Intermediate
1. 安全的文件操作 / Safe File Operations
-- 模式一:pcall 包裹
local function safeRead(path)
local file, err = io.open(path, "r")
if not file then return nil, err end
local content = file:read("*a")
file:close()
return content
end
local content, err = safeRead("missing.txt")
if not content then print("Error: " .. err) end
-- 模式二:确保文件关闭(类似 try-finally)
local function withFile(path, mode, fn)
local file, err = io.open(path, mode)
if not file then return nil, err end
local ok, result = pcall(fn, file)
file:close()
if not ok then error(result) end
return result
end
withFile("data.txt", "r", function(f)
for line in f:lines() do
print(line)
end
end)
2. 临时文件 / Temporary Files
-- 创建临时文件
local tmpname = os.tmpname()
print(tmpname) -- /tmp/lua_XXXXXX
local f = io.open(tmpname, "w")
f:write("temporary data")
f:close()
-- 使用完后删除
os.remove(tmpname)
-- io.tmpfile() 创建自动清理的临时文件
local tmp = io.tmpfile()
tmp:write("auto-cleaned")
tmp:seek("set", 0)
print(tmp:read("*a"))
tmp:close() -- 关闭时自动删除
3. 文件定位 / File Positioning
local f = io.open("test.txt", "r+")
-- seek(whence, offset)
-- whence: "set" (文件开头), "cur" (当前位置), "end" (文件末尾)
f:seek("set", 0) -- 回到文件开头
f:seek("end", -10) -- 从末尾倒数 10 字节
f:seek("cur", 5) -- 从当前位置前进 5 字节
local pos = f:seek() -- 获取当前位置
print(pos)
f:close()
4. 目录操作 / Directory Operations
-- Lua 没有内置的目录操作,但可以用 os.execute 或 lfs 库
-- 列出文件(Linux/macOS)
local function listFiles(dir)
local files = {}
local pipe = io.popen('ls -1 "' .. dir .. '"')
for file in pipe:lines() do
files[#files + 1] = file
end
pipe:close()
return files
end
-- os.execute 执行系统命令
os.execute("mkdir -p /tmp/lua_test")
os.execute("rm -f /tmp/lua_test/file.txt")
-- io.popen 执行命令并捕获输出
local pipe = io.popen("uname -a")
local sysinfo = pipe:read("*a")
pipe:close()
print(sysinfo)
-- LuaFileSystem (lfs) 库
-- local lfs = require("lfs")
-- lfs.chdir("/tmp")
-- lfs.mkdir("newdir")
-- for entry in lfs.dir(".") do print(entry) end
🔴 高级 / Advanced
1. 流式处理大文件 / Streaming Large Files
-- 逐行处理,不会一次性加载到内存
local function processLargeFile(path)
local file = assert(io.open(path, "r"))
local lineNum = 0
for line in file:lines() do
lineNum = lineNum + 1
-- 处理每一行
if lineNum % 10000 == 0 then
io.stderr:write("Processed " .. lineNum .. " lines\n")
end
end
file:close()
return lineNum
end
-- 分块读取二进制文件
local function readFileChunks(path, chunkSize)
chunkSize = chunkSize or 4096
local file = assert(io.open(path, "rb"))
return function()
local chunk = file:read(chunkSize)
if not chunk then file:close() end
return chunk
end
end
for chunk in readFileChunks("large.bin", 8192) do
-- 处理每个 chunk
end
2. os 库常用函数 / os Library Functions
os.time() -- 当前时间戳
os.date("*t") -- 当前日期时间表
os.date("%Y-%m-%d %H:%M:%S") -- 格式化日期
os.difftime(t2, t1) -- 两个时间戳的差(秒)
os.execute("command") -- 执行系统命令(返回状态码)
os.exit(0) -- 退出程序
os.getenv("PATH") -- 获取环境变量
os.remove("file.txt") -- 删除文件
os.rename("old", "new") -- 重命名
os.tmpname() -- 生成临时文件名
os.clock() -- CPU 时间(精度高于 os.time)
-- 实用:计时器
local start = os.clock()
-- ... 要计时的代码 ...
local elapsed = os.clock() - start
print(string.format("Time: %.3f seconds", elapsed))
小结 / Summary
| 层级 | 你需要知道的 / What You Need to Know |
|---|---|
| 🟢 基础 | io.open/close/read/write/lines、文件模式、标准 I/O |
| 🟡 进阶 | pcall 安全操作、临时文件、seek 定位、os.execute、io.popen |
| 🔴 高级 | 流式大文件处理、分块读取、os 库全貌、LuaFileSystem |