I/O库为文件操作提供了两种不同的模型,简单模型和完整模型。简单模型假设一个当前输入文件和一个当前输出文件,他的I/O操作均作用于这些文件。完整模型则使用显式的文件句柄,并将所有的操作定义为文件句柄上的方法。
    1. 简单模型:
    I/O库会将进程标准输入输出作为其缺省的输入文件和输出文件。我们可以通过io.input(filename)和io.output(filename)这两个函数来改变当前的输入输出文件。
    1). io.write函数:
    函数原型为io.write(...)。该函数将所有参数顺序的写入到当前输出文件中。如:
    io.write("hello","world") --写出的内容为helloworld

2). io.read函数:
    下表给出了该函数参数的定义和功能描述:

参数字符串 含义
"*all" 读取整个文件
"*line" 读取下一行
"*number" 读取一个数字
<num> 读取一个不超过<num>个字符的字符串

调用io.read("*all")会读取当前输入文件的所有内容,以当前位置作为开始。如果当前位置处于文件的末尾,或者文件为空,那个该调用返回一个空字符串。由于Lua可以高效的处理长字符串,因此在Lua中可以先将数据从文件中完整读出,之后在通过Lua字符串库提供的函数进行各种处理。
    调用io.read("*line")会返回当前文件的下一行,但不包含换行符。当到达文件末尾时,该调用返回nil。如:

for count = 1,math.huge do
local line = io.read("*line") --如果不传参数,缺省值也是"*line"
if line == nil then
break
end
io.write(string.format("%6d ",count),line,"\n")
end

如果只是为了迭代文件中的所有行,可以使用io.lines函数,以迭代器的形式访问文件中的每一行数据,如

1 local lines = {}
2 for line in io.lines() do --通过迭代器访问每一个数据
3 lines[#lines + 1] = line
4 end
5 table.sort(lines) --排序,Lua标准库的table库提供的函数。
6 for _,l in ipairs(lines) do
7 io.write(l,"\n")
8 end

调用io.read("*number")会从当前输入文件中读取一个数字。此时read将直接返回一个数字,而不是字符串。"*number"选项会忽略数字前面所有的空格,并且能处理像-3、+5.2这样的数字格式。如果当前读取的数据不是合法的数字,read返回nil。在调用read是可以指定多个选项,函数会根据每个选项参数返回相应的内容。如:

 1 --[[
2 6.0 -3.23 1000
3 ... ...
4 下面的代码读取注释中的数字
5 --]]
6 while true do
7 local n1,n2,n3 = io.read("*number","*number","*number")
8 if not n1 then
9 break
10 end
11 print(math.max(n1,n2,n3))
12 end

调用io.read(<num>)会从输入文件中最多读取n个字符,如果读不到任何字符,返回nil。否则返回读取到的字符串。如:

1 while true do
2 local block = io.read(2^13)
3 if not block then
4 break
5 end
6 io.write(block)
7 end

io.read(0)是一种特殊的情况,用于检查是否到达了文件的末尾。如果没有到达,返回空字符串,否则nil。

2. 完整I/O模型:
    Lua中完整I/O模型的使用方式非常类似于C运行时库的文件操作函数,它们都是基于文件句柄的。
    1). 通过io.open函数打开指定的文件,并且在参数中给出对该文件的打开模式,其中"r"表示读取,"w"表示覆盖写入,即先删除文件原有的内容,"a"表示追加式写入,"b"表示以二进制的方式打开文件。在成功打开文件后,该函数将返回表示该文件的句柄,后面所有基于该文件的操作,都需要将该句柄作为参数传入。如果打开失败,返回nil。其中错误信息由该函数的第二个参数返回,如:
    assert(io.open(filename,mode))  --如果打开失败,assert将打印第二个参数给出的错误信息。
    
    2). 文件读写函数read/write。这里需要用到冒号语法,如:

1 local f = assert(io.open(filename,"r"))
2 local t = f:read("*all") --对于read而言,其参数完全等同于简单模型下read的参数。
3 f:close()

此外,I/O库还提供了3个预定义的文件句柄,即io.stdin(标准输入)、io.stdout(标准输出)、io.stderr(标准错误输出)。如:
    io.stderr:write("This is an error message.")
    事实上,我们也可以混合使用简单模式和完整模式,如:

1 local temp = io.input()   --将当前文件句柄保存
2 io.input("newInputfile") --打开新的输入文件
3 io.input():close() --关闭当前文件
4 io.input(temp) --恢复原来的输入文件

3). 性能小技巧:
    由于一次性读取整个文件比逐行读取要快一些,但对于较大的文件,这样并不可行,因此Lua提供了一种折中的方式,即一次读取指定字节数量的数据,如果当前读取中的最后一行不是完整的一行,可通过该方式将该行的剩余部分也一并读入,从而保证本次读取的数据均为整行数据,以便于上层逻辑的处理。如:
    local lines,rest = f:read(BUFSIZE,"*line") --rest变量包含最后一行中没有读取的部分。
    下面是Shell中wc命令的一个简单实现。

 1 local BUFSIZE = 8192
2 local f = io.input(arg[1]) --打开输入文件
3 local cc, lc, wc, = 0, 0, 0 --分别计数字符、行和单词
4 while true do
5 local lines,rest = f:read(BUFSIZE,"*line")
6 if not lines then
7 break
8 end
9 if rest then
10 lines = lines .. rest .. "\n"
11 end
12 cc = cc + #lines
13 --计算单词数量
14 local _, t = string.gsub(lines."%S+","")
15 wc = wc + t
16 --计算行数
17 _,t = string.gsub(line,"\n","\n")
18 lc = lc + t
19 end
20 print(lc,wc,cc)

4). 其它文件操作:
    如io.flush函数会将io缓存中的数据刷新到磁盘文件上。io.close函数将关闭当前打开的文件。io.seek函数用于设置或获取当前文件的读写位置,其函数原型为f:seek(whence,offset),如果whence的值为"set",offset的值则表示为相对于文件起始位置的偏移量。如为"cur"(默认值),offset则为相对于当前位置的偏移量,如为"end",则为相对于文件末尾的偏移量。函数的返回值与whence参数无关,总是返回文件的当前位置,即相对于文件起始处的偏移字节数。offset的默认值为0。如:

1 function fsize(file)
2 local current = file:seek() --获取当前位置
3 local size = file:seek("end") --获取文件大小
4 file:seek("set",current) --恢复原有的当前位置
5 return size
6 end

最后需要指出的是,如果发生错误,所有这些函数均返回nil和一条错误信息。

更多:http://www.cnblogs.com/stephen-liu74/archive/2012/07/13/2426131.html very good。

Lua I/0输入输出的更多相关文章

  1. The Implementation of Lua 5.0 阅读笔记(一)

    没想到Lua的作者理论水平这么高,这篇文章读的我顿生高屋建瓴之感.云风分享了一篇中译:http://www.codingnow.com/2000/download/The%20Implementati ...

  2. The implementation of Lua 5.0 阅读笔记(二)

    6 线程和协程 读完这篇文章我才意识到python的协程到底缺了什么,这个就是coroutine和semi-coroutine的区别了.区别就是,semi-coroutine只能返回(yield)到调 ...

  3. lua 1.0 源码分析 -- 总结

    读完 lua1.0 的源码感触:1. 把复杂的代码写简单2. pack 的内存回收3. hash 实现简单,但是应该可以改进,看高版本的代码怎么实现4. lua 初始化环境做了什么,就是一组全局变量初 ...

  4. lua 1.0 源码分析 -- 2 内存回收

    说这个,先要说下 lua 的环境,正常说创建一个 lua 的虚拟环境,就是创建一组全局变量, lua1.0 里创建的主要是以下几个: extern Symbol *lua_table; /* 符号数组 ...

  5. lua 1.0 源码分析 -- 1 lua 的虚拟指令

    lua的解释器拿到 lua 编写的源码,首先进行解析,就是进行词法分析和语法分析,将源码转换成 lua 的指令集,然后执行这个指令集. lua 源码: function f(val) return v ...

  6. scheme I/0 输入输出操作

    2.1. open-input-file, read-char, and eof-object? The function (open-input-file filename) is availabl ...

  7. spring boot:用redis+lua实现基于ip地址的分布式流量限制(限流/简单计数器算法)(spring boot 2.2.0)

    一,限流有哪些环节? 1,为什么要限流? 目的:通过对并发请求进行限速或者一个时间单位内的的请求进行限速,目的是保护系统可正常提供服务,避免被压力太大无法响应服务. 如果达到限制速率则可以采取预定的处 ...

  8. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

  9. Lua语言中文手册 转载自网络

    Programming in LuaCopyright ® 2005, Translation Team, www.luachina.net Programming in LuaProgramming ...

随机推荐

  1. 泰晓科技 +兰大开源社区 +程序动态分析---LINUX内核网站

    http://www.tinylab.org/ http://linux-talents.tinylab.org/lzuoss/ http://www.tinylab.org/source-code- ...

  2. 安全通信 QSslSocket

    The QSslSocket class provides an SSL encrypted socket for both clients and servers. More... Header: ...

  3. 如何在windows/wamp环境下在本机配置站点

    1. 在D:\wamp\bin\apache\Apache2.5.4\conf文件夹下,找到httpd.conf,使用记事bej打开它,搜索#Include conf/extra/httpd-vhos ...

  4. Ant学习笔记(2) 在Eclipse中使用Ant

    Eclipse默认提供了对Ant的支持,在Eclipse中不需要安装任何插件就能直接编辑和运行Ant.Eclipse中包含了一个Ant脚本编辑器,Ant脚本编辑器提供了对Ant脚本的语法搞来高亮.自动 ...

  5. Codeforces 231E - Cactus

    231E - Cactus 给一个10^5个点的无向图,每个点最多属于一个环,规定两点之间的简单路:从起点到终点,经过的边不重复 给10^5个询问,每个询问两个点,问这两个点之间有多少条简单路. 挺综 ...

  6. rabbitmq 消息持久化

    rabbitmq 消息持久化 2016-02-18 11:19 224人阅读 评论(0) 收藏 举报  分类: 综合(15)  版权声明:本文为博主原创文章,未经博主允许不得转载. 二: 任务分发 & ...

  7. U3D 实现地面碰撞效果

    前面讲了如何让两个刚体碰撞: 现在来细细讲解一下, 首先,精灵刚体后就好比物理世界的物体,是受到重力所用的, 然后两个物体要添加碰撞系数才能实现碰撞, 这种情况下,碰撞后会使得另一个刚体也会随之运动, ...

  8. Android性能优化之ViewStub

    http://www.cnblogs.com/lwbqqyumidi/p/4047108.html ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Andro ...

  9. Spring MVC返回json数据给Android端

    原先做Android项目时,服务端接口一直是别人写的,自己拿来调用一下,但下个项目,接口也要自己搞定了,我想用Spring MVC框架来提供接口,这两天便抽空浅学了一下该框架以及该框架如何返回json ...

  10. SQL语句之三简单增删改查

    这是前面建的库和表 USE Test go INSERT dbo.MyTable --插入数据         ( NAME ,age) VALUES  ( '数据,20  -- NAME - var ...