美文网首页
六 输入输出

六 输入输出

作者: 愤愤的有痣青年 | 来源:发表于2020-12-17 10:26 被阅读0次

1. 简单的I/O模型

io.readio.write是从流中读入和输出数据的函数,使用io.inputio.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方式打开一个文件后,可以使用readwrite来读取和写出文件,其使用方式同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

相关文章

网友评论

      本文标题:六 输入输出

      本文链接:https://www.haomeiwen.com/subject/dxvagktx.html