Lua檔案處理
管理提醒:
本帖被 lua china 從 lua新手入門 移動到本區(2008-12-01)
一。檔案讀存:
-- 似乎不支援大檔案(不能超過9k?):
function opensavetest()
local file = io.open("c:\\in.lua", "r");
if(file) then
local data = file:read("*a"); -- i've also tried "*all" as described in PIL
file:close();
file = io.open("c:\\out.lua", "w");
if(file) then
file:write(data);
file:close();
end
end
end
opensavetest();
二。非循環表格處理(見program in lua):
HERO = 1 Monster = 2 Building = 3 SumUnit = 4
cha = {}
cha[1] =
{
basic =
{
Name = "農民" , --角色名稱
cha_type = HERO --角色模型類型
} ,
Combat =
{
acquire = 600.00 , --主動攻擊範圍
basic_def = 10 --基礎防禦
}
}
function serialize2( o)
if type(o) == "number" then
g_file:write(o)
elseif type(o) == "string" then
g_file:write(string.format("%q", o))
elseif type(o) == "table" then
g_file:write("{\n")
for k,v in pairs(o) do
g_file:write(" [")
serialize2(k)
g_file:write("] = ")
serialize2(v)
g_file:write(",\n")
end
g_file:write("}\n")
else
error("cannot serialize a " .. type(o))
end
end
function savetest ()
if g_file == nil then
print("error int 'savetest()'");
return;
end
g_file:write("cha = {}\n")
g_file:write("cha[1] = {\n")
serialize2( cha[1] );
g_file:write("}\n")
end
g_file = io.open("c:\\tt.lua", "w");
savetest();
g_file:close()
三。原program in lua中的儲存帶/不帶循環的table
12.1.1 儲存不帶循環的table
我們下一個艱巨的任務是儲存表。根據表的結構不同,采取的方法也有很多。沒有一種單一的算法對所有情況都能很好地解決問題。簡單的表不僅需要簡單的算法而且輸出檔案也需要看起來美觀。
我們第一次嘗試如下:
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
io.write("{\n")
for k,v in pairs(o) do
io.write(" ", k, " = ")
serialize(v)
io.write(",\n")
end
io.write("}\n")
else
error("cannot serialize a " .. type(o))
end
end
盡管代碼很簡單,但很好地解決了問題。隻要表結構是一個樹型結構(也就是說,沒有共享的子表并且沒有循環),上面代碼甚至可以處理嵌套表(表中表)。對于所進不整齊的表我們可以少作改進使結果更美觀,這可以作為一個練習嘗試一下。(提示:增加一個參數表示縮進的字元串,來進行序列化)。前面的函數假定表中出現的所有關鍵字都是合法的标示符。如果表中有不符合Lua文法的數字關鍵字或者字元串關鍵字,上面的代碼将碰到麻煩。一個簡單的解決這個難題的方法是将:
io.write(" ", k, " = ")
改為
io.write(" [")
serialize(k)
io.write("] = ")
這樣一來,我們改善了我們的函數的健壯性,比較一下兩次的結果:
-- result of serialize{a=12, b='Lua', key='another "one"'}
-- 第一個版本
{
a = 12,
b = "Lua",
key = "another \"one\"",
}
-- 第二個版本
{
["a"] = 12,
["b"] = "Lua",
["key"] = "another \"one\"",
}
我們可以通過測試每一種情況,看是否需要方括号,另外,我們将這個問題留作一個練習給大家。
12.1.2 儲存帶有循環的table
針對普通拓撲概念上的帶有循環表和共享子表的table,我們需要另外一種不同的方法來處理。構造器不能很好地解決這種情況,我們不使用。為了表示循環我們需要将表名記錄下來,下面我們的函數有兩個參數:table和對應的名字。另外,我們還必須記錄已經儲存過的table以防止由于循環而被重複儲存。我們使用一個額外的table來記錄儲存過的表的軌迹,這個表的下表索引為table,而值為對應的表名。
我們做一個限制:要儲存的table隻有一個字元串或者數字關鍵字。下面的這個函數序列化基本類型并傳回結果。
function basicSerialize (o)
if type(o) == "number" then
return tostring(o)
else -- assume it is a string
return string.format("%q", o)
end
end
關鍵内容在接下來的這個函數,saved這個參數是上面提到的記錄已經儲存的表的蹤迹的table。
function save (name, value, saved)
saved = saved or {} -- initial value
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 -- value already saved?
-- use its previous name
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
舉個例子:
我們将要儲存的table為:
a = {x=1, y=2; {3,4,5}}
a[2] = a -- cycle
a.z = a[1] -- shared sub-table
調用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]
(實際的順序可能有所變化,它依賴于table周遊的順序,不過,這個算法保證了一個新的定義中需要的前面的節點都已經被定義過)
如果我們想儲存帶有共享部分的表,我們可以使用同樣table的saved參數調用save函數,例如我們建立下面兩個表:
a = {{"one", "two"}, 3}
b = {k = a[1]}
儲存它們:
save('a', a)
save('b', b)
結果将分别包含相同部分:
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"
然而如果我們使用同一個saved表來調用save函數:
local t = {}
save('a', a, t)
save('b', b, t)
結果将共享相同部分:
a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = a[1]
上面這種方法是Lua中常用的方法,當然也有其他一些方法可以解決問題。比如,我們可以不使用全局變量名來儲存,即使用封包,用chunk構造一個local值然後傳回之;通過構造一張表,每張表名與其對應的函數對應起來等。Lua給予你權力,由你決定如何實作。
文章來源于 http://www.luaer.cn
轉載于:https://www.cnblogs.com/penglink/archive/2009/10/13/1582859.html