Lua I/O 库用于读取和处理文件。分为简单模式(和C一样)、完全模式。
简单模式(simple model)拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。\
完全模式(complete model) 使用外部的文件句柄来实现。它以一种面对对象的形式,将所有的文件操作定义为文件句柄的方法
简单模式在做一些简单的文件操作时较为合适。但是在进行一些高级的文件操作的时候,简单模式就显得力不从心。例如同时读取多个文件这样的操作,使用完全模式则较为合适。
1、打开文件
file = io.open (filename [, m]) 打开文件,返回文件句柄file,filename为文件名,m模式可选:
r 以只读方式打开文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
r+ 以可读写方式打开文件,该文件必须存在。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a+ 与a类似,但此文件可读可写
b 二进制模式,如果文件是二进制文件,可以加上b
+ 号表示对文件既可以读也可以写
2、简单模式
io.input() 设置默认的输入文件,file为文件名(或文件句柄),返回文件句柄。
io.output() 设置默认的输出文件,参数意义同上。
io.close() 关闭文件,不带参数关闭默认的文件
io.read(formats) 读入默认文件,formats取值为"*a"(读入全部)、“*n”(按数字读入)、 "*l"(按行读入,默认方式)、n(即数字,读取n个字符)。
io.write(value)向默认文件写入内容。
io.flush() 把文件缓存里的操作立即作用到默认输出文件。
io.lines(optional file name) 返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件
使用举例
写文件:
1 2 3 4 5 6 7 8 9 10 11 12 | --以只写方式打开文件 file = io.open("myfile","w") --设置默认输出文件为myfile io.output(file) --写入两行,可加入转义字符\n io.write("These are test words\n") io.write("Add second line into myfile") --关闭打开的文件 io.close(file) |
读文件:
1 2 3 4 5 6 7 8 9 10 11 | --以只读方式打开文件 file = io.open("myfile","r+") --设置默认输入文件 io.input(file) --读取所有内容 print(io.read("*a")) --关闭打开的文件 io.close(file) |
3、完全模式
若file为文件句柄(file = io.open("myfile","r+")),则可进行如下操作:
file :close ()
file :read ( formats ) formats取值为"*a"(读入全部)、“*n”(按数字读入)、 "*l"(按行读入,默认方式)、n(即数字,读取n个字符)。
file :lines ()
file :write ( values )
file :seek ( [, of]) 设置文件读写的偏移,p文件偏移起始位置(取值有"set",文件头,此为默认值,"cur"当前位置、"end"文件尾),of偏移量(默认值0,正的表示向前,负的表示向后),返回在文件里新的当前位置。
file :flush () 向文件写入缓冲中的所有数据
使用举例
1 2 3 4 5 6 7 8 9 10 | --写 file = io.open("myfile","a+") file:write("\nAdd another line") file:close() --读 file = io.open("myfile","r") print(file:read("*a")) file:close() |
4、一些方便使用的文件io函数
迭代,读取文件所有单词,返回单词内容,修改%w可完成匹配筛选功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function allwords (filename) local file = io.open(filename, "r") io.input(file) local line = io.read() local pos = 1 return function () while line do local s, e = string.find(line,"%w+",pos) if s then pos = e + 1 return string.sub(line,s,e) else line = io.read() pos = 1 end end return nil end end |
迭代,读取文件每一行,返回line,value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function allwords (filename) local file = io.open(filename, "r") io.input(file) local line = io.read() local pos = 1 return function () while line do local s, e = string.find(line,"%w+",pos) if s then pos = e + 1 return string.sub(line,s,e) else line = io.read() pos = 1 end end return nil end end |
迭代,读取文件每一行,返回line,value
1 2 3 4 5 6 7 8 9 10 11 12 | function myall (filename) local file = io.open(filename, "r") local i = 0 io.input(file) return function () i=i+1 v=io.read() if v then return i,v end end end |
读取一个较大的文件
1 2 3 4 5 6 7 8 9 | function read_file(filename) local file = io.open(filename,"r") local t = {} for lines in file:lines() do t[#t+1] = lines end result = table.concat(t,"\n") --将table中的元素相连,用换行符隔开 return result end |
filename中的非ascii字符(中文等)和=号全转化为16进制表示
1 2 3 4 5 6 7 8 9 | function transtest (filename) file=io.open(filename,"a+") io.input(file) t=io.read("*all") t=string.gsub(t,"([\128-\255=])",function(s) return string.format("=%02X",string.byte(s)) end) io.write(t) end |
输出每行最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | --1 function maxline(filename) local file=io.open("a","r") io.input(file) for v in io.lines() do local lines={} for word in string.gmatch(v,"%d+") do lines[#lines+1]=tonumber(word) end print(math.max(lines[1],lines[2],lines[3])) end end --2 function maxline2(filename) local file=io.open("a","r") io.input(file) local pat="(%S+)%s+(%S+)%s+(%S+)%s+" for n1,n2,n3 in string.gmatch(io.read("*all"),pat) do n1=tonumber(n1) n2=tonumber(n2) n3=tonumber(n3) print(math.max(n1,n2,n3)) end end |
统计文件中的字符cc、行数lc、单词数wc
1 2 3 4 5 6 7 8 9 10 11 12 13 | function words(filename) local cc,lc,wc=0,0,0 local file=io.open(filename,"r") while true do local lines = file:read("*line") if not lines then break end cc=cc+#lines local _,t=string.gsub(lines,"%S+","") wc=wc+t lc=lc+1 end print(cc,lc,wc) end |
获取文件大小
1 2 3 4 5 6 7 | function fsize(filename) local file=io.open(filename,"r") local current=file:seek() --获取当前位置(此时为0) local size=file:seek("end") --hu获取文件大小(包括换行符) local current2=file:seek() --获取当前位置(此时为end的位置) print(current,size,current2) end |