FileIO.lua
------------------------------------ 文件I/O ------------------------------------
-- Lua的I/O库用于读取和处理文件,其提供了两种不同风格的接口;
-- (1) 隐式文件句柄,简单模式;
-- 1. 提供默认的输入\输出文件,所有的输入输出操作都针对这文件;
-- 2. 所有的操作都由表io提供;
-- (2) 显式文件句柄,完全模式;
-- 1. 通过io.open获取外部文件的句柄,并操作外部的文件;
-- 2. 所有的操作通过file句柄(io.open返回值)来完成;
do
local ioMumb = ''
for k, v in pairs(io) do
ioMumb = ioMumb .. k .. ' '
end
print(ioMumb) --> popen output stdout close stderr type input flush read lines stdin tmpfile write open
end
------- (1) 隐式文件句柄,简单模式
--- 预定义文件句柄(与C含义相同):io.stdin、io.stdout、io.stderr
-- io.stdin即键盘;io.stdout即屏幕
print("标准输入文件:" .. tostring(io.stdin)) --> 标准输入文件:file (568527D8)
print("标准输出文件:" .. tostring(io.stdout)) --> 标准输出文件:file (56852810)
print("标准错误文件:" .. tostring(io.stderr)) --> 标准错误文件:file (56852848)
--- io.open(filename[,mode])
-- 已字符串mode指定的模式打开一个文件;
-- 返回值:成功返回文件句柄;
-- 失败返回nil + 错误消息;
-- mode字符串:
-- "r": 读模式(默认,且文件要存在);
-- "w":写模式(不存在文件则自动创建);
-- "a":追加模式(不存在文件则自动创建);
-- "r+":更新模式;(原数据保留,且文件要存在)
-- "w+":更新模式;(原数据删除,不存在文件则自动创建)
-- "a+":追加更新模式;(原数据保留,且只能在文件尾部写入,不存在文件则自动创建)
file1 = io.open("./myfile1.txt","a+")
print(type(file1)) -- userdata
--- io.type(obj)
-- 检查obj是否是合法的文件句柄;
-- 返回值:打开的文件,返回"file"
-- 关闭的文件,返回"closed file"
-- 不是文件句柄,返回nil
print(io.type(file1)) --> file
print(io.type(123)) --> nil
--- io.close([file])
-- 关闭file文件;
-- 不指定时,默认关闭输出文件;
io.close(file1)
--- io.read(...)
-- 从文件中读取内容;(默认是标准输入文件io.stdin)
-- 参数: 1. "*n"表示读取一个数字; 2. "*a"表示从当前位置读取余下所有内容;
-- 3. "*l"表示读取下一行内容; 4. numbers表示读取字节数;
a = io.read("*n") -- 键盘输入123abcde
print("io.read(\"*n\") " .. a) --> io.read("*n")123
b = io.read(3) -- 之前读取了数字123后,还剩下abcde,这里在读取3个字节,即abc
print("io.read(\"3\") " .. b) --> io.read("3")abc
c = io.read() -- 读取剩余的bc
print("io.read(\"\") " .. c) --> io.read("")de
--- io.write(...)
-- 向文件中写入内容;(默认是标准输出文件io.stdout)
-- 返回值: 成功返回 "file"; 失败返回nil;
io.write("1+1= ", 2, '\n') --> 1+1= 2
io.write(a,b,c,'\n') --> 123abcde
--- io.output([file])
-- 打开一个文件,并把这个文件作为默认输出文件;(不存在file文件,则会自动新建一个)
-- 参数:文件路径(会覆盖原数据) 或 文件句柄(根据打开的类型操作)
-- 返回值:文件句柄
str1 = [[
hello
lua5.3
]]
str2 = [[
hello
world
]]
-- 用法(1)
file1 = io.output("./myfile1.txt")
io.write(str1)
io.close(file1)
-- 用法(2)
file2 = io.open("./myfile2.txt","w")
io.output(file2)
io.write(str2)
io.close(file2)
-- 恢复标准输出文件(即屏幕)
io.output(io.stdout)
io.write("恢复标准输出文件\n") --> 恢复标准输出文件
--- io.input([file])
-- 打开一个文件,并把这个文件作为默认输入文件;(不存在file文件,则会自动新建一个)
-- 参数:文件路径(会覆盖原数据) 或 文件句柄(根据打开的类型操作)
-- 返回值:文件句柄
-- 用法(1)
file1 = io.input("./myfile1.txt")
print(io.read("*a")) --> hello / lua5.3
io.close(file1)
-- 用法(2)
file2 = io.open("./myfile2.txt","r")
io.input(file2)
print(io.read("*a")) --> hello / world
io.close(file2)
-- 恢复标准输入文件(即键盘)
io.output(io.stdout)
io.write("恢复标准输入文件\n") --> 恢复标准输入文件
--- io.lines([filename])
-- 以读的模式打开一个文件,并且返回一个迭代函数;(默认io.stdin)
-- 该迭代函数每一次被调用都会返回文件中新的一行的内容,直到文件中所有的内容都被读完;
str1 = ''
str2 = ''
-- 用法(1)
for line in io.lines("./myfile1.txt") do
str1 = str1 .. line
end
print(str1) --> hellolua5.3
-- 用法(2)
file2 = io.open("./myfile2.txt","r") -- 打开文件
io.input(file2) -- 设置默认输入文件
for line in io.lines() do
str2 = str2 .. line
end
print(str2) --> helloworld
io.input(io.stdin) -- 恢复输入文件
io.close(file2) -- 关闭文件
--- io.flush()
-- 把用户程序中的缓冲区数据强制写入到文件或内存变量并清空缓冲区;
-- 作用在默认的输出文件上;(可以通过io.output修改默认输出文件)
--- io.tmpfile()
-- 返回一个临时文件的句柄;(以更新模式打开的)
tmpfile = io.tmpfile() -- 获取临时文件句柄
io.output(tmpfile) -- 设置为默认输出文件
io.write("a = 100\n")
tmpfile:write("b = \"hello\"")
io.output(io.stdout) -- 恢复默认输出文件
tmpfile:seek("set") -- 移动文件指针到开头
content = tmpfile:read("*a") -- 读取临时文件内容
print(content) --> a = 100 / b = "hello"
io.close(tmpfile) -- 关闭文件
--- io.popen(prog[,mode])
-- 在额外的进程中启动程序prog,并返回用于prog的文件句柄;(即调用一个命令程序)
-- 参数mode: r(默认):从这个程序中读取数据;
-- w:从这个程序中写入数据;
-- (有点类似于os.execute())
do
-- 打开文件(这个文件保存的是命令ipcondig的结果)
local secondfile = io.popen("ipconfig")
print("\n======commond ipconfig result:")
-- 读取文件内容
local content = secondfile:read("*a")
print(content) -- 可以在cmd中输入ipconfig查看结果(win10)
end
------- (2) 显式文件句柄,完全模式
-- 打开文件并获取句柄
file = io.open("myFile.txt","w+")
--- file:setvbuf(mode[,size])
-- 设置输出文件的缓冲模式;
-- mode参数:
-- "no":不缓冲;输出操作立刻生效;
-- "full":完全缓冲;当缓存满时 或者 对file显式调用flush时;
-- "line":行缓冲;缓冲到换行前,对于某些文件则缓冲到任何输入前;
file:setvbuf("full",100)
--- file:write()
-- 将参数的值,诸葛写入file;
-- 返回值:成功返回 "file"; 失败返回nil;
file:write(
[[这里是第一行
这里是第二行
这里是第三行
]],"这里是第四行","这里也是第四行")
io.read() -- 此处等待输入,打开myFile.txt看看,没有内容;
--- file:flush()
-- 将写入的数据保存到file中;
file:flush()
io.read() -- 此处等待输入,打开myFile.txt看看,刷新后已看到内容;
--- file:seek([whence[,offset]])
-- 设置及获取基于文件开头处计算出的位置;
-- whence参数:
-- "set":基点为0;(文件开头)
-- "cur":基点为当前位置;
-- "end":基点为文件结尾;
file:seek("set",6*3+2) -- 6个文字,每个文字3个字节,加1个‘\n’
--- file:read(...)
-- 读取file文件,由指定的格式决定读什么内容;(默认"*l")
-- 返回值:成功:读出的字符串或数字;
-- 结尾或失败:返回nil;
-- 格式:"*n":读取1个数字;("0x" 或 "3.4e-"构成的都不是合法数字)
-- "*i":读取1个整数;
-- "*a":从当前位置开始,读取整个文件;
-- "*l":读取一行;(忽略行结束标记)
-- "*L":读取一行;(保留行结束标记)
-- number:读取的字节数;
print(file:read("*l")) --> 这里是第二行
--- file:lines()
-- 返回一个迭代函数,按指定格式读取文件;(默认是"*l")
-- 与io.lines([file])不同,本函数结束后并不会关闭文件;
file:seek("set") -- 将文件指针定位到开头
do
local str = ''
for line in file:lines("*l") do
str = str .. line .. " "
end
print(str) --> 这里是第一行 这里是第二行 这里是第三行 这里是第四行这里也是第四行
end
--- file:close
-- 关闭file;(文件句柄被垃圾回收时,会自动关闭)
file:close()