Lua 文件操作:io.open() 与 io.read()
在 Lua 中读取或写入文件,核心靠两个函数:io.open() 打开文件,io.read() 从已打开的文件中读取内容。掌握它们的配合使用,就能完成绝大多数本地文件读取任务。
第一步:用 io.open() 打开文件
调用 io.open() 函数来打开一个文件。它需要两个参数:
- 文件路径(字符串)
- 打开模式(字符串)
常用模式包括:
"r":只读(默认),文件必须存在"w":只写,会清空原文件内容"a":追加写入"rb"/"wb":以二进制模式读/写(跨平台更安全)
执行以下代码打开当前目录下的 data.txt 文件用于读取:
local file = io.open("data.txt", "r")
如果文件不存在或路径错误,io.open() 返回 nil 和一条错误信息。务必检查返回值是否有效:
local file, err = io.open("data.txt", "r")
if not file then
print("打开失败:", err)
return
end
第二步:用 io.read() 从文件读取内容
注意:io.read() 默认从标准输入(如键盘)读取。要让它从你刚打开的文件读取,必须先将文件设为当前输入流,或直接在文件对象上调用 read 方法。
方法一:设置全局输入流(不推荐)
io.input(file) -- 将 file 设为默认输入
local content = io.read("*all") -- 读全部内容
这种方式会影响后续所有 io.read() 调用,容易引发混乱。
方法二:直接在文件对象上调用 read()(推荐)
调用文件对象的 :read() 方法,这是最清晰、安全的做法:
local line = file:read("*line") -- 读一行(不含换行符)
local all = file:read("*all") -- 读整个文件
local n = file:read(10) -- 读10个字符
常见读取模式说明:
| 模式参数 | 作用说明 |
|---|---|
"*all" |
读取文件剩余全部内容,返回一个字符串 |
"*line" |
读取下一行(到换行符为止),不包含换行符;文件末尾返回 nil |
n(数字) |
读取最多 n 个字符;若不足则读到文件末尾 |
示例:逐行读取文件
local file = io.open("log.txt", "r")
if not file then return end
while true do
local line = file:read("*line")
if not line then break end -- 到达文件末尾
print("读到一行:", line)
end
file:close()
第三步:关闭文件
调用 :close() 方法关闭文件,释放系统资源:
file:close()
即使脚本结束时 Lua 会自动关闭文件,也必须显式关闭——否则在长时间运行的程序中可能耗尽文件句柄。
更稳妥的做法是使用 “确保关闭”模式:
local file, err = io.open("config.ini", "r")
if not file then
error("无法打开 config.ini: " .. err)
end
-- 正常处理
local data = file:read("*all")
-- 立即关闭
file:close()
或者用 pcall + 匿名函数实现类似 try-finally 的效果(高级用法):
local function withFile(filename, mode, callback)
local f, err = io.open(filename, mode)
if not f then error(err) end
local ok, result = pcall(callback, f)
f:close()
if not ok then error(result) end
return result
end
-- 使用
local content = withFile("notes.txt", "r", function(f)
return f:read("*all")
end)
常见错误与避坑指南
-
忘记检查
io.open()是否成功
直接对nil调用:read()会报错:attempt to index a nil value。始终先判断文件是否打开成功。 -
混淆
io.read()和file:read()
io.read()操作的是标准输入(通常是终端),除非你调用了io.input(file)。优先使用file:read()。 -
路径问题
Lua 使用相对路径时,基准是程序启动时的工作目录,不是脚本所在目录。若需脚本目录下的文件,可用:local script_dir = arg[0]:match("(.*[/\\])") local filepath = (script_dir or "") .. "myfile.txt" -
二进制文件误用文本模式
读取图片、音频等二进制文件时,必须使用"rb"模式,否则在 Windows 上可能因换行符转换导致数据损坏。 -
未处理编码问题
Lua 默认按字节处理文件,不涉及字符编码。若文件含中文等非 ASCII 字符,读出的是原始字节串。如需 UTF-8 解析,需额外处理(Lua 本身无内置支持)。
完整示例:安全读取整个文件
function readFile(path)
local file, err = io.open(path, "r")
if not file then
return nil, "打开文件失败: " .. tostring(err)
end
local content = file:read("*all")
file:close()
return content
end
-- 使用
local text, errmsg = readFile("example.txt")
if text then
print("文件内容长度:", #text, "字节")
else
print(errmsg)
end
暂无评论,快来抢沙发吧!