好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Lua输入输出库

Lua输入输出库

  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。如:

 1   for  count =  1 , math.huge   do 
2 local line = io.read ( " *line " ) -- 如果不传参数,缺省值也是"*line"
3 if line == nil then
4 break
5 end
6 io.write ( string.format ( " %6d " ,count),line, " \n " )
7 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和一条错误信息。

 

分类:  Lua编程

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Lua输入输出库的详细内容...

  阅读:54次