文件读写基础
1 ) 文件打开 (io.open)
功能:创建文件句柄,指定访问模式
| 模式 | 功能说明 | 适用场景 |
|---|---|---|
| r | 只读模式,默认值,文件需存在 | 读取配置文件、日志文件 |
| w | 覆盖写入模式,不存在则新建 | 生成全新输出文件、覆盖备份 |
| a | 追加写入模式 | 日志追加、内容补充 |
| r+ | 读写模式,文件需存在 | 编辑现有文件内容 |
| w+ | 读写模式,清空原有内容 | 创建可编辑的临时文件 |
| a+ | 读写追加模式 | 同时读取旧内容并追加新内容 |
| rb/wb | 二进制读写模式 | 处理图片、音频等二进制文件 |
模式参数:
"r":只读(默认)"w":写入(覆盖原内容)"a":追加(文件末尾写入)"r+":读写更新(保留原数据)"b":二进制模式(如 “rb”)
local file = io.open("test.txt", "r") -- 只读模式打开
assert(file, "文件打开失败!") -- 结合assert检查错误
2 ) 文件读取 (file:read)
读取选项:
"*a":读取整个文件"*l":读取一行(默认)"*n":读取一个数字n:读取n个字节(如file:read(10))
local content = file:read("*a") -- 读取全部内容
3 ) 文件写入 (file:write)
写入字符串或数据到文件
local file = io.open("log.txt", "a") -- 追加模式
file:write("New log entry\n") -- 写入一行
4 ) 关闭文件 (file:close)
释放资源,避免内存泄漏
file:close() -- 显式关闭文件
文件读写核心代码
以下为可直接运行的基础操作示例:
1 ) 读取文件全部内容
--- 以只读模式打开文件,使用assert捕获打开异常
local file = assert(io.open("test.txt", "r"), "文件打开失败,请检查路径是否正确")
--- 一次性读取文件所有内容
local content = file:read("*a")
print("读取到的文件内容:")
print(content)
file:close()
2 ) 写入并追加文件内容
--- 以覆盖模式打开文件,不存在则自动创建
local file = assert(io.open("output.txt", "w"))
file:write("Hello Lua 文件写入测试\n")
file:close()
--- 追加内容到文件末尾
local append_file = assert(io.open("output.txt", "a"))
append_file:write("追加第二行测试内容")
append_file:close()
错误处理机制
1 ) 语法错误检查
常见错误:运算符误用(如 = 与 ==)、缺少关键字(如 for 循环缺 do)
for i = 1, 10 do -- 正确:循环体需用 do ... end
print(i)
end
2 ) 运行时错误捕获
核心函数用法对照如下:
| 函数 | 功能描述 | 代码示例 |
|---|---|---|
| assert() | 校验条件,不满足则抛出指定错误信息 | assert(type(count) == “number”, “count 必须为数字类型”)[[8]] |
| error() | 主动抛出错误,可指定错误层级 | if not file then error(“文件操作执行失败”, 2) end[[14]] |
| pcall() | 保护模式调用函数,捕获错误不终止程序 | local ok, err = pcall(file.read, file) if not ok then print(“读取错误:”, err) end[[3]] |
| xpcall() | 带错误处理函数的保护调用,可获取完整栈追踪 | local status = xpcall(read_file, debug.traceback) print(status)[[3]] |
-
assert(condition, message):条件为假时抛出错误
local num = "abc" assert(type(num) == "number", "非数字类型!") -- 抛出错误 -
pcall(func, …):保护模式调用函数,返回状态和错误信息
local success, err = pcall(function() error("自定义错误") end) if not success then print("错误:", err) end -
xpcall(func, err_handler):提供自定义错误处理函数
local function handle_err(err) print("错误详情:", debug.traceback(err)) end xpcall(errorfunction, handleerr)
3 )文件操作中的错误处理
结合 assert 与 io.open 确保文件有效:
local file, err = io.open("missing.txt", "r")
if not file then
print("打开失败:", err) -- 输出错误信息
return
end
完整示例:文件复制(含错误处理)
--- 安全复制文件
local function copyfile(srcpath, dst_path)
-- 打开源文件(带错误检查)
local src, err = io.open(src_path, "rb")
if not src then
return false, "源文件打开失败: " .. err
end
-- 读取内容
local content, read_err = src:read("*a")
if not content then
src:close()
return false, "读取失败: " .. (read_err or "未知错误")
end
src:close()
--- 写入目标文件
local dst, openerr = io.open(dstpath, "wb")
if not dst then
return false, "目标文件创建失败: " .. open_err
end
dst:write(content)
dst:close()
return true, "复制成功"
end
-- 执行复制并处理结果
local ok, msg = copy_file("source.txt", "target.txt")
print(ok and "成功" or "失败", msg)
工程示例
1 ) 示例1
--- 1. 读取文件内容
function readFile(filename)
local file, err = io.open(filename, "r")
if not file then
print("错误: 无法打开文件 " .. filename .. " - " .. err)
return nil
end
local content = file:read("*a") -- 读取所有内容
file:close()
return content
end
--- 2. 写入文件内容(覆盖)
function writeFile(filename, content)
local file, err = io.open(filename, "w")
if not file then
print("错误: 无法打开文件 " .. filename .. " - " .. err)
return false
end
file:write(content)
file:close()
return true
end
--- 3. 追加内容到文件
function appendToFile(filename, content)
local file, err = io.open(filename, "a")
if not file then
print("错误: 无法打开文件 " .. filename .. " - " .. err)
return false
end
file:write(content)
file:close()
return true
end
--- 使用示例
local data = readFile("input.txt")
if data then
print("文件内容: " .. data)
appendToFile("output.txt", "追加内容\n")
end
writeFile("output.txt", "新内容覆盖\n")
2 ) 示例2
--- 1. 使用 assert 检查参数
function divide(a, b)
assert(type(a) == "number", "第一个参数必须是数字")
assert(type(b) == "number", "第二个参数必须是数字")
assert(b ~= 0, "除数不能为零")
return a / b
end
--- 2. 使用 pcall 捕获错误
function safeCall(fn, ...)
local status, result = pcall(fn, ...)
if status then
print("函数执行成功,结果: " .. tostring(result))
return result
else
print("函数执行出错: " .. result)
return nil
end
end
--- 3. 使用 xpcall 捕获错误并获取堆栈信息
function detailedCall(fn, ...)
local status, result = xpcall(fn, debug.traceback, ...)
if status then
print("函数执行成功,结果: " .. tostring(result))
return result
else
print("函数执行出错,详细信息:\n" .. result)
return nil
end
end
--- 使用示例
safeCall(divide, 10, 2) -- 成功
safeCall(divide, 10, 0) -- 出错,被捕获
detailedCall(divide, "string", 5) -- 出错,带堆栈信息
3 )示例3
-- 安全读取文件(带错误处理)
function safeReadFile(filename)
local file, err = io.open(filename, "r")
if not file then
print("错误: 打开文件失败 - " .. err)
return nil
end
local content, readErr = file:read("*a")
if not content then
print("错误: 读取文件失败 - " .. readErr)
file:close()
return nil
end
file:close()
return content
end
-- 安全写入文件(带错误处理)
function safeWriteFile(filename, content)
local file, err = io.open(filename, "w")
if not file then
print("错误: 创建/打开文件失败 - " .. err)
return false
end
local status, writeErr = file:write(content)
if not status then
print("错误: 写入文件失败 - " .. writeErr)
file:close()
return false
end
file:close()
return true
end
-- 使用示例
local data = safeReadFile("config.txt")
if data then
print("读取成功: " .. data)
else
print("读取失败,使用默认配置")
safeWriteFile("config.txt", "default_setting=true\n")
end
进阶技巧
1 ) 文件定位 (file:seek)
移动读写位置:
file:seek("set", 0) -- 移动到文件开头
local pos = file:seek() -- 获取当前位置
2 ) 二进制文件处理
使用 “b” 模式读写非文本文件(如图片)
3 ) 批量读写优化
逐行处理大文件:
for line in file:lines() do -- 迭代读取每行
process(line)
end
建议结合调试工具(如 debug.traceback)定位复杂错误
学习总结与建议
1 ) 所有文件操作完成后必须调用file:close()释放系统资源,避免内存泄漏
2 ) 开发阶段优先使用assert()快速校验参数与文件状态,简化代码冗余
3 ) 生产环境中建议搭配xpcall()与debug库记录完整错误栈,便于后续问题排查
1237

被折叠的 条评论
为什么被折叠?



