简单的I/O模型(输出→写入;输入→读取)
- 输出:从lua程序中输出数据到文件,及写入文件
-
io.input():将文件加入输入流(读取)
io.input([filename]):设置filename这个文件为当前标准输入流,并返回该文件的描述符
io.input([filename]):设置filename这个文件为当前标准输入流,并返回该文件的描述符,同时会清空文件内容
在io.input()和io.output()在设定文件后,输入和输出都来自所设定文件,除非重新设定
- 在设定io.input()后:
- io.read()为读取输入流的字符
- io.write()为写入输出流,但此时输出流代表的是打印
- 在设定io.output()后:
- io.read()程序将会停止在该语句,因为没有设定输入流,程序在等待输入流设定;
- io.write()为写入输出流,此时会将写入的字符串写入指定的文件中(会先清空文件所有内容)
- 一次只能存在一个输出流和输入流
-
io.read():读取输入流字符串
io.read([option,…]):从输入流中读取字符串,返回读取到的字符串,如果文件为空或读取到文件末尾,则返回空字符串(nil);可以通过设置参数来修改读取方式
- option:可选参数,用于选择读取方式,不使用则为读取一行(及默认为”l”)
- 一次使用多个option,则一次使用option的功能
- 如:io.read(“l”,”n”):即为读取下一行,读取一个数字,同时返回2个结果
- 注:如果在io.input()后使用io.read(),可能出现输入流没有内容导致程序等待,或输出输入流内容
- 注:io.read()实际上是io.input():read()的简写 | option对应功能 | | | —- | —- | | “a” | 读取整个文件 | | “l” | 读取下一行(丢弃换行符) | | “L” | 读取下一行(保留换行符) | | “n” | 往后读取一个数值,如果往后的不是数值(只能忽略空格,\t),则返回nil,可读取int和float | | num | 以字符串读取num个字符(一次读取num个保存到一个字符串中) |
注:lua5.2之前需要在之前加上(如:”a”),lua5.2之后不需要加上*,但是仍然保留了该方法
io.write():读取字符到输出流
- io.write(…):读取任意数量字符串,并写入输出流
- 参数是任意多个的
- io.write()在最后的输出结果中不会添加换行符(\n)和制表符(print中使用,)等额外内容
- 使用string.format()来控制格式
- 参数为nil会发生报错
- 注:在io.input()后为打印字符;在io.output()后为写入字符到文件
- 注:io.read()实际上是io.output():write()的简写 ```lua —[[ 读取文件的内容为: hello world —this is line 1 this is test.txt —this is line 2 1 2.0 35 36.2 —this is line 3 —]]
print(“====================================”) print(io.input(“Chapter 7\test.txt”)) —返回设定 所读取文件描述符 print(io.input()) —返回当前读取文件的描述符
print(“====================================”) t = io.read() —默认为读取一行 io.write(t) —输出:hello world —this is line 1
print(“\n====================================”)
io.input(“Chapter 7\test.txt”) —重新载入
t = io.read(“a”) —读取全部
io.write(t)
—[[
输出:
hello world —this is line 1
this is test.txt —this is line 2
1 2.0 35 36.2 —this is line 3
—]]
print(“\n====================================”)
io.input(“Chapter 7\test.txt”) —重新载入
t = io.read(“l”) —读取一行(不带换行符)
io.write(t)
io.write(t)
—输出:hello world —this is line 1hello world —this is line 1
print(“\n====================================”) io.input(“Chapter 7\test.txt”) —重新载入 t = io.read(“L”) —读取一行(带换行符) io.write(t) io.write(t) —[[ 输出: hello world —this is line 1 hello world —this is line 1 —]]
print(“\n====================================”) io.input(“Chapter 7\test.txt”) —重新载入 —t=io.read(“n”) 由于开头不是数字,所以返回nil io.read(“l”,”l”) —读取2行 t1, t2, t3, t4 = io.read(“n”, “n”, “n”, “n”) —读取4个数子 print(t1, t2, t3, t4) —输出:1 2.0 35 36.2
print(“\n====================================”) io.input(“Chapter 7\test.txt”) —重新载入 t = io.read(2) —读取两个连续的字符 io.write(t, “\n”) —输出:he t = io.read(3) —读取三个连续的字符 io.write(t) —输出:llo
print(“\n====================================”) print(io.output(“Chapter 7\test.txt”)) —返回所读取文件描述符,会清空文件内容 print(io.output()) —返回结果同上 io.write(“this is change”) —写入文件,此时文件内容只有写入的这一句 io.close() —关闭文件流 print(“io is close”)
<a name="f7GR3"></a>
## io.lines():逐行迭代
- Lua5.2开始,io.lines()可以使用io.read()的参数
```lua
io.input("Chapter 7\\test.txt")
lines = {}
count = 1
for line in io.lines() do --使用io.lines()直接对输入流进行逐行迭代
lines[count] = line
count = count + 1
end
for k, v in pairs(lines) do
print(v)
end
--[[
输出:
hello world --this is line 1
this is test.txt --this is line 2
1 2.0 35 36.2 --this is line 3
]]
--对文件进行按块(8KB)读取
for block in io.input():lines(2 ^ 13) do
--io.lines()一次读取输入流的2^13内容,在这些2^13内容中进行逐行迭代
io.write(block)
end
完整I/O模型
简单I/O模型在上一个输入输出流完成处理之前只能处理一个输入输出流,完整I/O模型可以在不关闭其余输入输出流的情况下处理多个输出输出流
io.open():打开文件流
io.open(filename[,mode]):使用对应的mode,打开文件流;返回文件流标识符;打开失败,则返回nil和出错原因
- filename:要加入文件流的文件名
- mode:处理文件地文件流模式 | mode模式对应 | | | —- | —- | | r | 以只读方式打开,文件必须存在(不会创建文件,可用该方法来检测文件是否存在) | | w | 以只写方式打开,文件不存在则创建文件;存在,则文件内容消失文件重新写入 | | a | 以附加方式打开,文件不存在则创建文件;存在,则在文件末尾最后写入 | | b | 二进制模式 | | + | 表示文件即可读又可写,如:r+,w+ |
:read():从文件流中读取
- read([option]):使用方法与简单I/O模型中的io.read()相同
- 在文件流标识符后使用:read()
- 一定要使用”:“ | option对应功能 | | | —- | —- | | “a” | 读取整个文件 | | “l” | 读取下一行(丢弃换行符) | | “L” | 读取下一行(保留换行符) | | “n” | 往后读取一个数值,如果往后的不是数值(只能忽略空格,\t),则返回nil,可读取int和float | | num | 以字符串读取num个字符(一次读取num个保存到一个字符串中) |
:write():写入文件流
- read([option]):使用方法与简单I/O模型中的io.read()相同
- 在文件流标识符后使用:write()
- 一定要使用”:“
-
:close():关闭文件流
关闭文件流 ```lua file1, error = io.open(“test.txt”, “r”) —使用r模式打开test.txt文件 print(file1, error) —因为不存在该文件,输出:文件标识符 test.txt: No such file or directory
print(“====================================”) file1, error = io.open(“test.txt”, “w”) —使用w模式打开test.txt文件 print(file1, error) —因为不存在该文件,但是该模式下会自动创建该文件,输出:文件标识符 nil
print(“====================================”) file1, error = io.open(“Chapter 7\test.txt”, “r”) —使用r模式打开hapter 7\test.txt文件 print(file1, error) —该文件存在,输出:文件标识符 nil
print(“====================================”) t = file1:read(“a”) —对文件流使用:read()方法中的a方式 print(t) —输出所有 result = file1:write(“this is add”) —对r模式打开的文件流使用:write()方法 print(result) —因为r模式文件流无法写,所以返回nil
print(“====================================”)
—[[
file1=io.open(“Chapter 7\test.txt”,”w”) —使用w模式打开Chapter 7\test.txt文件
result=file1:write(“this is add line\n”) —对文件流使用:write()方法,并且获得返回值
print(result)
—[[
返回文件流的标识符,并且原本的文件内容消失,变为:
this is add line
—]]
—]]
print(“====================================”) file2 = io.open(“Chapter 7\test.txt”, “a+”) —使用a+模式打开Chapter 7\test.txt文件 t = file2:read() —对文件流使用:read()方法,读取第一行 print(t) —输出:hello world —this is line 1 file2:write(“this is add line\n”) —对文件流使用:write()方法,写入字符串,该模式下会在文件末尾追加 文件内容变为 —[[ hello world —this is line 1 this is test.txt —this is line 2 1 2.0 35 36.2 —this is line 3 this is addthis is add line —]]
file1:close() —关闭文件流 file2:close()
<a name="rJi0X"></a>
# 其他文件操作
<a name="ySVDP"></a>
## io.tmpfile():创建并返回临时文件
- **io.tmpfile()**:**创建临时文件**,并**返回**临时文件**句柄**,可以以**读/写模式**使用,在程序结束后**自动删除临时文件**
```lua
tmpfile=io.tmpfile() --创建临时文件及其标识符
tmpfile:write("this is line 1\n") --:write方法写入数据
tmpfile:write("this is line 2")
tmpfile:seek("set") --将读取位置移至文件开始位置
t=tmpfile:read("a") --读取全部内容
print(t)
--[[
输出:
this is line 1
this is line 2
--]]
io.flush():强制将缓存流写入
io.flush()/:flush():将缓冲流中的数据强制写入文件,清空缓冲区
:setvbuf(mode[,size]):设置流缓冲区模式,和缓冲区大小
- mode:缓冲模式
- size:可选参数,设定缓冲区的大小 | mode的模式对应 | | | —- | —- | | “full” | 满缓冲模式,缓冲区满时写入,不满则不写入 | | “line” | 行缓冲模式,每次只读入或写入一行数据 | | “no” | 无缓冲模式,直接读入或写入 |
file=io.open("test.txt","w") --使用w模式将文件加入文件流
file:setvbuf("full",16) --设置缓冲区为full模式,缓冲区大写为16字节
file:write("10 letters\n") --写入文件流
file:write("10 letters\n")
--[[
由于设定为full模式,且大小为16,所以只有在缓冲区满16字节时,才会写入,
此时的test.txt中的文件内容为:
10 letters
10 le
剩余的tters\n部分,由于缓存没满没所以不会写入
--]]
os.execute("pause") --暂停执行,知道按下按键
file:flush() --强制将缓冲区写入
--[[
将缓冲区所有数据强制写入,此时文件内容为:
10 letters
10 letters
--]]
os.execute("pause")
file:close()
:seek():获取和设置文件当前位置
- seek([whence][,offset]):用于设定文件当前位置,返回文件当前位置
- whence:可选参数,默认为cur。指定偏移模式
- offset:可选参数,默认为0,表示偏移位置,可谓负数
- 返回的值永远是,当前位置相对文件开头的偏移 | whence的模式对应 | | | —- | —- | | “cur” | 相对文件当前位置的偏移 | | “set” | 相对文件开头的偏移 | | “end” | 相对文件尾部的偏移 |