天天看點

lua檔案處理

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

lua