lua文件读写


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