简单的I/O模型(输出→写入;输入→读取)

  • 输出:从lua程序中输出数据到文件,及写入文件
  • 输入:从文件中读取数据到lua程序,及读取文件

    io.input():将文件加入输入流(读取)

  • io.input([filename])设置filename这个文件为当前标准输入流,并返回该文件的描述符

    • 不使用参数:返回当前文件的描述符
    • 设置后,之后的所有输入(指io.read()函数)都来自读取该文件

      io.output():将文件加入输出流(写入)

  • io.input([filename])设置filename这个文件为当前标准输入流,并返回该文件的描述符,同时会清空文件内容

    • 不使用参数:返回当前文件的描述符
    • 设置后,之后的所有写入(指io.write()函数)都写入该文件

      io.input()和io.output()

  • 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”)

  1. <a name="f7GR3"></a>
  2. ## io.lines():逐行迭代
  3. - Lua5.2开始,io.lines()可以使用io.read()的参数
  4. ```lua
  5. io.input("Chapter 7\\test.txt")
  6. lines = {}
  7. count = 1
  8. for line in io.lines() do --使用io.lines()直接对输入流进行逐行迭代
  9. lines[count] = line
  10. count = count + 1
  11. end
  12. for k, v in pairs(lines) do
  13. print(v)
  14. end
  15. --[[
  16. 输出:
  17. hello world --this is line 1
  18. this is test.txt --this is line 2
  19. 1 2.0 35 36.2 --this is line 3
  20. ]]
  21. --对文件进行按块(8KB)读取
  22. for block in io.input():lines(2 ^ 13) do
  23. --io.lines()一次读取输入流的2^13内容,在这些2^13内容中进行逐行迭代
  24. io.write(block)
  25. 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():将缓冲流中的数据强制写入文件,清空缓冲区

    • io.flush():作用在默认输出文件上
    • :flush()/io.flush(file):作用在特定输出文件描述符上

      :setvbuf():设置流的缓冲模式

  • :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” | 相对文件尾部的偏移 |