快速掌握Lua 5.3 —— I/O库 (1)
来源:互联网 发布:织梦 文章分页 index 编辑:程序博客网 时间:2024/05/22 16:54
Q:什么是”Simple Model”?
A:所有的文件操作都基于一个默认的输入文件和一个默认的输出文件,这就意味着同一时间对于输入和输出来说,只可操作一个文件(默认的文件)。默认的输入文件初始化是stdin
,默认的输出文件初始化是stdout
,
-- "a.lua"文件中:--[[ "io.read()"从"io.input()"所指定的默认输入文件中读; "io.write()"向"io.output()"所指定的默认输出文件中写。 因为默认输入文件初始化是"stdin";默认的输出文件初始化是"stdout", 所以"io.read()"从"stdin"读;"io.write()"向"stdout"写。]]io.write(io.read())--[[ result: > lua a.lua Hello World! Hello World!]]
io.read()
和io.write()
都可以接收多个参数,
-- "a.lua"文件中:io.write(io.read(), " and", " The Complete I/O Model.")--[[ result: > lua a.lua The Simple I/O Model The Simple I/O Model and The Complete I/O Model.]]
io.input()
和io.output()
可以更改对应的默认文件,
-- "file1.txt"文件中:Hello World!-- "a.lua"文件中:local temp_input = io.input() -- 保存原先的默认输入文件(此时是"stdin")。local temp_output = io.output() -- 保存原先的默认输出文件(此时是"stdout")。io.input("file1.txt") -- 指定默认的输入文件为"file1.txt"。io.output("file2.txt") -- 指定默认的输出文件为"file2.txt"。io.write(io.read())io.input():close() -- 关闭"file1.txt"。io.output():close() -- 关闭"file2.txt"。io.input(temp_input) -- 恢复原先的默认输入文件。io.output(temp_output) -- 恢复原先的默认输出文件。--[[ result: > lua a.lua > cat file2.txt Hello World!]]
Q:print()
与io.write()
有什么区别?
A:
1、print()
在打印其每个参数之间增加\t
,且最后增加\n
,而io.write()
均不会。
print("hello", "Lua")print("Hi")--[[ result: hello Lua Hi]]io.write("hello", "Lua")io.write("Hi", "\n")--> helloLuaHi
2、io.write()
向io.output()
指定的文件中写(初始值是stdout
),而print()
总向stdout
写。
-- "a.lua"文件中:local temp = io.output()io.output("file3.txt")io.write("Hello")print(" World")io.output():close()io.output(temp)--[[ result: "file3.txt"文件中: Hello "stdout": World]]
3、print()
对于不能被直接打印的对象会自动调用tostring()
转换,而io.write()
不会。
t = {}print(t) --> table: 0x1ca9aa0io.write(t) --> error
Q:io.read()
的参数?
A:
-- "file1.txt"文件中:line1line2line3-- "data.txt"文件中:6.0 -3.23 15e124.3 234 1000001
1、*a
从当前的文件读取位置读取到文件尾,如果文件为空或者已在文件尾,则返回空串,
local temp = io.input()io.input("file1.txt")io.write(io.read("*a"))io.input():close()io.input(temp)--[[ result: line1 line2 line3]]
2、*l
从当前的文件读取位置读取到行尾,不包含结尾的\n
;*L
与*l
功能相同,但包含行尾的\n
。如果文件为空或者已在文件尾,则返回nil
,
local temp = io.input()io.input("file1.txt")str = ""local i = 1while true do local s if i == 2 then s = io.read("*L") else s = io.read("*l") -- "io.read()"不指定参数时,默认使用"*l"参数。 end if s == nil then break end -- 当文件读取完时,返回"nil"。 str = str .. s i = i + 1endio.write(str)--[[ result: line1line2 line3]]io.input():close()io.input(temp)
3、*n
从当前的文件读取位置读取一个数值。io.read("*n")
返回数值,而不是字符串。当需要从一个文件中读取大量数字时,数字间的字符串为空格可以显著提高执行性能。io.read("*n")
会跳过两个可被识别数字之间的任意空格,如果在当前位置找不到一个数字(由于格式不对,或者是到了文件的结尾),则返回nil
。
-- 打印文件每一行中最大的数字。local temp = io.input()io.input("data.txt")while true do local n1, n2, n3 = io.read("*n", "*n", "*n") if not n1 then break end print(math.max(n1, n2, n3))endio.input():close()io.input(temp)--[[ result: 15000000000000.0 1000001]]
4、io.read(num)
可以指定一个数字,lua将尽可能读取”num”个字符(如果不够则能读多少读多少),如果文件为空或者已读取到文件尾则返回nil
。
local temp = io.input()io.input("data.txt")io.write(io.read(3)) -- 读取3个字符。print()-- 读取100个字符。但实际没有那么多,所以能读取多少读多少。io.write(io.read(100))io.input():close()io.input(temp)--[[ result: 6.0 -3.23 15e12 4.3 234 1000001]]
Q:其他的”Simple Model”模式的库函数?
A:
--[[ io.tmpfile() 以"w+"的模式打开一个临时文件,并返回其文件句柄。 当程序运行结束时,该文件会被自动删除。]]local f = io.tmpfile()f:write("123")f:seek("set", 0) -- 将文件的当前读取位置定位到文件头。print(f:read()) -- 123f:close()--[[ io.type(obj) 检查"obj"是否为有效的文件句柄。函数返回如下: "file": 如果"obj"是一个被打开的文件句柄。 "closed file": 如果"obj"是一个被关闭的文件句柄。 nil: 如果"obj"不是一个有效的文件句柄。]]print(io.type(f)) -- nilf = io.tmpfile()print(io.type(f)) -- filef:close()print(io.type(f)) -- closed file
附加:
1、io.input()
和io.output()
在出错时均会报错。如果想控制错误,请使用”Complete model”下的io.open()
。
2、向io.write()
传递的数字参数会被自动转换为字符串。如果想完全控制转换,最好使用string.format()
。
io.write("sin(3) = ", math.sin(3), "\n")--> sin(3) = 0.14112000805987io.write(string.format("sin(3) = %.4f\n", math.sin(3)))--> sin(3) = 0.1411
3、避免写io.write(a..b..c)
这样的代码,io.write(a, b, c)
能够完成相同的工作,同时避免了..
操作符复制字符串所耗费的内存资源。
4、当文件为空,或者文件当前的读取位置在文件尾时,io.read("*a")
会返回空字符串,而io.read("*l")
、io.read("*L")
、io.read("*n")
和io.read(num)
都会返回nil
。
5、如果想要逐行的读取文件,相比io.read("*l")
,更好的选择是io.lines()
。io.lines()
可以指定想要读取的文件,并且可以指定多个,依次的按行读取这些文件。同时在读取完毕后,io.lines()
会自动关闭文件。
-- 为文件的每一行增加行号。-- "file1.txt"文件中。line1line2line3-- "a.lua"文件中。local count = 1for line in io.lines("file1.txt") do io.write(string.format("%6d ", count), line, "\n") count = count + 1end--[[ result: > lua a.lua 1 line1 2 line2 3 line3]]
然而如果io.lines()
不带参数,则与io.read()
的功能相同,同时在读取完毕后不会关闭文件。
6、如果对于文件需要逐块的操作,但最终会操作整个文件。那么最好使用io.read("*a")
读取整个文件,然后使用string.gmatch()
分解出需要操作的块,
-- 上面打印文件每一行中最大的数字的例子。-- 需要处理的块,一个或多个非空格加上一个或多个空格……local block = "(%S+)%s+(%S+)%s+(%S+)%s+"--[[ "string.gmatch()"返回的结果是字符串形式的, 如果直接传递给"math.max()"会按照字符串形式比较大小, 所以需要使用"tonumber()"转换为数字。]]for n1, n2, n3 in string.gmatch(io.read("*a"), block) do print(math.max(tonumber(n1), tonumber(n2), tonumber(n3)))end
省去了多次读文件的操作,效率会更高。
7、在Lua中拷贝文件的高效的方式,
local size = 2^13 -- good buffer size (8K)while true do local block = io.read(size) if not block then break end io.write(block)end
8、io.read(0)
测试是否到了文件尾。如果未到,则返回空字符串,如果到了则返回nil
。
- 快速掌握Lua 5.3 —— I/O库 (1)
- 快速掌握Lua 5.3 —— I/O库 (2)
- 快速掌握Lua 5.3 —— 字符串库 (1)
- 快速掌握Lua 5.3 —— 调试库 (1)
- 快速掌握Lua 5.3 —— 函数
- 快速掌握Lua 5.3 —— Coroutines
- 快速掌握Lua 5.3 —— 数据结构
- 快速掌握Lua 5.3 —— 环境
- 快速掌握Lua 5.3 —— packages
- 快速掌握Lua 5.3 —— 资源管理
- 快速掌握Lua 5.3 —— "table"库
- 快速掌握Lua 5.3 —— 字符串库 (2)
- 快速掌握Lua 5.3 —— 字符串库 (3)
- 快速掌握Lua 5.3 —— 操作系统库
- 快速掌握Lua 5.3 —— 调试库 (2)
- 快速掌握Lua 5.3 —— "metatables" and "metamethods" (1)
- 快速掌握Lua 5.3 —— userdata (1)
- 快速掌握Lua 5.3 —— 编写提供给Lua使用的C库函数的技巧 (1)
- 【小镇的技术天梯】刷票与防刷票的思考
- Android中怎么切换task到前台
- 自定义ViewGroup之卫星菜单
- VC模态和非模态对话框关闭过程
- 【leetcode】【17】Letter Combinations of a Phone Number
- 快速掌握Lua 5.3 —— I/O库 (1)
- linux下使用yum安装mysql
- 阻塞与非阻塞I/O
- React Native学习之TabBarIOS用法
- 用最少的代码写出求3个数最大值的函数
- 今日BBC
- (转)Django 1.6 最佳实践: 如何正确的使用和设置Database和Model
- Hibernate防止SQL注入攻击的方法
- [yael安装]编译时如何解决undefined reference to symbol sincos错误