上一篇: Lua基础学习(四)https://blog.youkuaiyun.com/sun_zeliang/article/details/86698691
Lua文件I/O
简单I/O模型
简单I/O模型假设有一个当前输入文件和一个当前输出文件,它的I/O操作均作用于这些文件。
打开文件操作语句:
file = io.open(filename [,mode])
mode 的值有:
模式 | 描述 |
---|---|
r | 以只读方式打开文件,该文件必须存在。 |
w | 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。 |
a | 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留) |
r+ | 以可读写方式打开文件,该文件必须存在。 |
w+ | 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 |
a+ | 与a类似,但此文件可读可写 |
b | 二进制模式,如果文件是二进制文件,可以加上b |
+ | 号表示对文件既可以读也可以写 |
简单示例:
file = io.output("test.txt") --设置输出文件
io.write("简单I/O模型--测试文件") --写入一行
io.close(file)
io.input("test.txt") --设置输入文件
print(io.read()) --输出文件第一行
输出:
设置输出文件的时候文件是不需要存在的,但是设置输出文件的时候文件必须存在!
io.read() 还可以带参数,参数分别如下:
"*l" | 读取一行,默认的就是这个 |
"*a" | 读取整个文件 |
"*n" | 读取一个数字 |
number | 返回一个不超过number个数的字符串 |
特殊io.read(0) 用来检查是否到达了文件末尾。还有数据可以读取返回空的字符串,否则返回nil。
其他的 io操作:
-
io.tmpfile():返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除
-
io.type(file): 检测obj是否一个可用的文件句柄
-
io.flush(): 向文件写入缓冲中的所有数据
-
io.lines(optional file name): 返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件
完整I/O模型
完整I/O模型则使用显式的文件句柄,它采用了面向对象的风格,并将所有的操作定义为文件句柄上的方法。
示例:
local file = io.open("test.txt","a")
file:write("完整I/O模型--测试文件")
file:write("\r")
file:close()
local file = assert(io.open("test.txt","r"))
local str = file:read("*a")
print(str)
file:close()
输出:
io.read() 使用的参数和简单I/O模型一样
其他IO操作:
-
file:seek(optional whence, optional offset): 设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息。参数 whence 值可以是:
- "set": 从文件头开始
- "cur": 从当前位置开始[默认]
- "end": 从文件尾开始
- offset:默认为0
-
file:flush(): 向文件写入缓冲中的所有数据
-
io.lines(optional file name): 打开指定的文件filename为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,并自动关闭文件。
若不带参数时io.lines() <=> io.input():lines(); 读取默认输入设备的内容,但结束时不关闭文件
Lua错误处理
错误有语法错误和运行错误
assert和error函数
error函数
error(message [,number])
功能:终止正在执行的函数,并返回message的内容作为错误信息(error函数永远都不会返回)
通常情况下,error会附加一些错误位置的信息到message头部。
number参数指示获得错误的位置:
- number=1[默认]:为调用error位置(文件+行号)
- number=2:指出哪个调用error的函数的函数
- number=0:不添加错误位置信息
示例:
local a = "Lua"
local b
if not a then error("error! "..a.." is nil") end
print(a.." is a string")
if not b then error("error!",2) end
print(b)
输出:
assert 函数
assert首先检查第一个参数,若没问题,assert不做任何事情;否则,assert以第二个参数作为错误信息抛出。
示例:
assert(type("lua")=="string","lua不是一个string")
assert(io.open("lua.txt","r"),"文件不存在!")
输出:
pcall 和 xpcall、debug
Lua中处理错误,可以使用函数pcall(protected call)来包装需要执行的代码。
pcall接收一个函数和要传递给后者的参数,并执行,执行结果:有错误、无错误;返回值true或者或false, errorinfo。
格式:
if pcall(函数名称) then
--没有错误的操作
else
--有错误的操作
end
pcall参数里面也可以是匿名函数
简单示例:
local a = "abc"
local b = 4
local c
if pcall( function() c=a+b end) then
print(c)
else
print("error")
end
输出:
pcall以一种"保护模式"来调用第一个参数,因此pcall可以捕获函数执行中的任何错误。
通常在错误发生时,希望落得更多的调试信息,而不只是发生错误的位置。但pcall返回时,它已经销毁了调用桟的部分内容。
Lua提供了xpcall函数,xpcall接收第二个参数——一个错误处理函数,当错误发生时,Lua会在调用桟展开(unwind)前调用错误处理函数,于是就可以在这个函数中使用debug库来获取关于错误的额外信息了。
debug库提供了两个通用的错误处理函数:
- debug.debug:提供一个Lua提示符,让用户来检查错误的原因
- debug.traceback:根据调用桟来构建一个扩展的错误消息
实例:
function f(a,b)
return a + b
end
function errorHandler(err)
print("ERROR:",err)
end
status = xpcall((function() print(f(5,4)) end),errorHandler)
print(status)
输出:
如果最后调用的那行修改为:
status = xpcall((function() print(f("dasd",4)) end),function() print(debug.traceback()) end)
输出 :