持久化
写一个文件容易,读一个文件难。健壮的程序应该能正确读取文件,还能处理坏文件。
数据描述是Lua的主要应用之一,从Lua发明以来,我们花了很多心血使他能够更快的编译和运行大的chunks。也即是说lua文件即可存储数据。
--使用lua文件作为数据数据,并进行管理的例子。
-------------- 数据文件data.lua
Entry{
author = "Donald E. Knuth",
title = "Literate Programming",
publisher = "CSLI",
year = 1992
}
Entry{
author = "Jon Bentley",
title = "More Programming Pearls",
publisher = "Addison-Wesley",
year = 1990
}
-------------- 数据文件data.lua
local authors = {} -- a set to collect authors
function Entry (b) -- Entry即可作为统计工具,记录数据。
if b.author then
authors[b.author] = true
end
end
序列化
不带循环嵌套的表
function serialize (o)
if type(o) == "number" then
io.write(o)
elseif type(o) == "string" then
io.write(string.format("%q", o))
elseif type(o) == "table" then
-- 如果是以下这种循环或者嵌套的表,就会死循环。
-- a = {x=1, y=2; {3,4,5}}
-- a[2] = a -- cycle
-- a.z = a[1]
a = {}
io.write("{\n")
for k,v in pairs(o) do
io.write(" [")
serialize(k)
io.write("] = ")
serialize(v)
io.write(",\n")
end
io.write("}\n")
else
error("cannot serialize a " .. type(o))
end
end
local t = {
a=12,
b='Lua',
key='another "one"'
}
serialize(t)
{
["a"] = 12,
["b"] = "Lua",
["key"] = "another \"one\"",
}
带循环嵌套的表
function basicSerialize (o) --一般序列化:number、string
if type(o) == "number" then
return tostring(o)
else -- assume it is a string
return string.format("%q", o)
end
end
-- name :key值
-- value :value值,可能是自循环table
-- saved :save表,保存已经序列化过的table,反之自循环table导致的死循环。
键值对:value(table) - name
function save(name, value, saved)
saved = saved or {}
io.write(name, " = ")
if type(value) == "number" or type(value) == "string" then
io.write(basicSerialize(value), "\n")
elseif type(value) == "table" then
if saved[value] then
io.write(saved[value], "\n")
else
saved[value] = name -- save name for next time
io.write("{}\n") -- create a new table
for k,v in pairs(value) do -- save its fields
local fieldname = string.format("%s[%s]", name,
basicSerialize(k))
save(fieldname, v, saved)
end
end
else
error("cannot save a " .. type(value))
end
end
----------------------------------------
a = {x=1, y=2; {3,4,5}}
a[2] = a
a.z = a[1]
save('a', a) --序列化自循环表
a = {}
a[1] = {}
a[1][1] = 3
a[1][2] = 4
a[1][3] = 5
a[2] = a
a["y"] = 2
a["x"] = 1
a["z"] = a[1]
----------------------------------
a = {{"one", "two"}, 3}
b = {k = a[1]}
save('a', a) -- 不同save表
save('b', b) -- 不同save表
a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = {}
b["k"][1] = "one"
b["k"][2] = "two"
--------------------------------
a = {{"one", "two"}, 3}
b = {k = a[1]}
local t = {}
save('a', a, t) --共同save表
save('b', b, t) --共同save表
a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = a[1]