21.2.1 I/O优化的一个小技巧 |
由于通常Lua中读取整个文件要比一行一行的读取一个文件快的多。尽管我们有时候针对较大的文件(几十,几百兆),不可能把一次把它们读取出来。要处理这样的文件我们仍然可以一段一段(例如8kb一段)的读取它们。同时为了避免切割文件中的行,还要在每段后加上一行:
local lines, rest = f:read(BUFSIZE, "*line")
以上代码中的rest就保存了任何可能被段划分切断的行。然后再将段(chunk)和行接起来。这样每个段就是以一个完整的行结尾的了。以下代码就较为典型的使用了这一技巧。该段程序实现对输入文件的字符,单词,行数的计数。
local BUFSIZE = 2^13 -- 8K
local f = io.input(arg[1]) -- open input file
local cc, lc, wc = 0, 0, 0 -- char, line, and word counts
while true do
local lines, rest = f:read(BUFSIZE, "*line")
if not lines then break end
if rest then lines = lines .. rest .. '\n' end
cc = cc + string.len(lines)
-- count words in the chunk
local _,t = string.gsub(lines, "%S+", "")
wc = wc + t
-- count newlines in the chunk
_,t = string.gsub(lines, "\n", "\n")
lc = lc + t
end
print(lc, wc, cc)