1. 简单的I/O模型
io.read
和io.write
是从流中读入和输出数据的函数,使用io.input
和io.output
可以指定输入输出流的文件来源,若不设置此参数,则默认为从当前的输入输出流.
因此在不设置io.input
的情况下可以使用io.read()
来读取用户的输入,使用io.write
来输出数据.
io.write
> io.write("hello world") --> hello worldfile (0x7f571b920620)
> io.output("test.txt")
> io.write("hello world") --> file (0x10ba1b0)
> io.close() --> true # 此时输出数据到了文本test.txt中
io.read
> io.read() --> # 此时会阻塞,并等待用户的输入
> io.input("test.txt")
> io.read() --> hello world
io.read
函数中,还可以指定参数,该参数决定要读取的数据:
参数 | 说明 |
---|---|
"a" | 读取整个文件 |
"l" | 读取下一行(舍弃换行符) |
"L" | 读取下一行(保留换行符) |
"n" | 读取一个数值 |
num |
以字符串读取num 个字符 |
io.lines
io.lines
函数是将文件作为一个迭代器返回,可以对其进行循环读取
io.input("test.txt")
for line in io.lines() do
print(line)
end
io.lines
函数中可以接收同io.read
一样的参数.
完整I/O模型
简单的I/O模型无法应对需要同时对多文件进行处理的场景,对此就需要使用完整了个I/O模型.
可以使用函数io.open
来打开一个文件,其仿照了 C语言的fopen
函数,因此其使用方式都是大同小异.其接收两个参数,一个是文件名,还有一个是打开的模式,如io.open("name", "r")
,其中关于模式的说明如下:
模式字符 | 说明 |
---|---|
"r" | 只读打开 |
"w" | 只写打开 |
"a" | 追加 |
"b" | 可选模式,以二进制的形式打开 |
io.open
函数如果执行失败,其会返回三个参数,分别是nil
错误信息
错误码
,如下
> print(io.open("不存在的文件","r"))
nil 不存在的文件: No such file or directory 2
> print(io.open("/etc/passwd","w"))
nil /etc/passwd: Permission denied 13
使用io.open
方式打开一个文件后,可以使用read
和write
来读取和写出文件,其使用方式同f.read f.write
类似,但但是需要使用冒号运算符将其作为流对象的方法来调用.
> local f=io.open("test.txt","rb")
> local t=f:read("a")
> print(t) --> hello world
> f:close()
I/O库提供了三个预定义的C语言流句柄:io.stdin io.stdout和io.stderr. 例如.可以使用如下代码来讲信息写到标准错误流中:
io.stderr:write("error info")
其他文件操作
- io.tmpfile 此函数返回一个操作临时文件的句柄,该句柄是以读/写模式打开的,当程序运行结束后,该文件会被自动删除.
- flush 将所有的缓冲数据写入文件.可以用
io.flush
的方式调用,表明刷新当前输出流,也可以以f:flush
调用,表明刷新f
输出流. - setvbuf 用于设置流的缓冲模式.该函数的第一个参数是一个字符串: "no"表示无缓冲,"full"表示在缓冲区满时或者显示的刷新文件时才写入数据,"line"表示输出一直被缓冲,直达遇到换行符或从一些特定文件(例如终端设备)中读取到了数据.对于后两种选项,其还支持可选的第二个采纳数,用于指定缓冲区的大小.
在大多数的系统中,标准错误流io.stderr
是不缓冲的,实时输出,但标准输出流io.stdin
是按行缓冲的. - seek 用来获取和设置文件的当前位置,常常使用
f:seek(whence, offset)
的形式来调用,其中参数whence
是一个指定如何使用偏移的字符串:set
表示相对于文件的开头偏移;取值cur
是相对于当前位置的偏移;取值end
时是相对于文件尾部的偏移.不管whence
的取值是什么,该函数都会以字节为单位,返回当乞丐了新位置在流中相对于文件开头的偏移.
whence
的默认值为cur
,offset
的默认值为0,因此调用函数file:seek()
表示获取当前位置且不改变当前位置;调用file:set("set")
表示返回文件的开头;调用file:set("end")
表示返回文件的结尾.
下面的函数样式了如何在不修改当前位置的情况下获取文件大小:
function fsize(file)
local cur = file:seek() -- 保存当前位置
local size = file:seek("end") -- 获取文件大小
file:seek("set", cur) -- 恢复文件位置
return size
end
-
io.rename
用来重命名文件os.remove
用来删除文件.这两个函数遇到错误时,会返回nil
外加一条错误信息和一个错误码.
其他系统调用
- os.exit 用于终止程序的执行.
- os.getenv 用于获取某个系统变量,对于未定义的变量返回nil
- os.execute 用于运行系统命令,返回值为命令运行结束后的状态.其中第一个返回值是一个布尔类型,当为
true
是表示程序成功运行完成;第二个返回值是一个字符串,当为exit
时表示程序正常运行结束,单位signal
表示因信号而中断;第三个返回状态(若程序正常终结)或者终结该程序的信号代码. - os.popen 同os.execute 函数一样,可以运行系统命令,但与之不同的是,此函数可重定向命令的输入/输出,从而使得程序可以向命令中写入或从命令的输出中读取.例如下列的代码是将当前目录下的文件构建为一个表:
function files()
local f = io.popen('ls ./', 'r')
local files = {}
for file in f:lines() do
files[#files+1] = file
end
return files
end
网友评论