- --[[
- file name : table序列化和反序列化的問題.lua
- author : Clark/陳澤丹
- created : 2011-12-22
- 備註:
- 支持table的遞歸結構,但數據類型不支持function屬性(因爲function只是記錄地址,在不同機器上序列化和反序列化後的地址相同沒什麼意義)
- 後記:
- 鬱悶, 寫完到網上一搜, 才發現原來Lua有提供一些現成的函數可用來做序列化和反序列化操作。。。
- 其中loadstring可以執行字符串。
- 通過
- lua = "return " .. lua
- local func = loadstring(lua)
- 即實現了反序列化。。。
- --]]
- ----------- 個人編寫 -----------------
- --table轉字符串(只取標準寫法,以防止因系統的遍歷次序導致ID亂序)
- function sz_T2S(_t)
- local szRet = "{"
- function doT2S(_i, _v)
- if "number" == type(_i) then
- szRet = szRet .. "[" .. _i .. "] = "
- if "number" == type(_v) then
- szRet = szRet .. _v .. ","
- elseif "string" == type(_v) then
- szRet = szRet .. '"' .. _v .. '"' .. ","
- elseif "table" == type(_v) then
- szRet = szRet .. sz_T2S(_v) .. ","
- else
- szRet = szRet .. "nil,"
- end
- elseif "string" == type(_i) then
- szRet = szRet .. '["' .. _i .. '"] = '
- if "number" == type(_v) then
- szRet = szRet .. _v .. ","
- elseif "string" == type(_v) then
- szRet = szRet .. '"' .. _v .. '"' .. ","
- elseif "table" == type(_v) then
- szRet = szRet .. sz_T2S(_v) .. ","
- else
- szRet = szRet .. "nil,"
- end
- end
- end
- table.foreach(_t, doT2S)
- szRet = szRet .. "}"
- return szRet
- end
- --字符串轉table(反序列化,異常數據直接返回nil)
- function t_S2T(_szText)
- --棧
- function stack_newStack()
- local first = 1
- local last = 0
- local stack = {}
- local m_public = {}
- function m_public.pushBack(_tempObj)
- last = last + 1
- stack[last] = _tempObj
- end
- function m_public.temp_getBack()
- if m_public.bool_isEmpty() then
- return nil
- else
- local val = stack[last]
- return val
- end
- end
- function m_public.popBack()
- stack[last] = nil
- last = last - 1
- end
- function m_public.bool_isEmpty()
- if first > last then
- first = 1
- last = 0
- return true
- else
- return false
- end
- end
- function m_public.clear()
- while false == m_public.bool_isEmpty() do
- stack.popFront()
- end
- end
- return m_public
- end
- function getVal(_szVal)
- local s, e = string.find(_szVal,'"',1,string.len(_szVal))
- if nil ~= s and nil ~= e then
- --return _szVal
- return string.sub(_szVal,2,string.len(_szVal)-1)
- else
- return tonumber(_szVal)
- end
- end
- local m_szText = _szText
- local charTemp = string.sub(m_szText,1,1)
- if "{" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- end
- function doS2T()
- local tRet = {}
- local tTemp = nil
- local stackOperator = stack_newStack()
- local stackItem = stack_newStack()
- local val = ""
- while true do
- local dLen = string.len(m_szText)
- if dLen <= 0 then
- break
- end
- charTemp = string.sub(m_szText,1,1)
- if "[" == charTemp or "=" == charTemp then
- stackOperator.pushBack(charTemp)
- m_szText = string.sub(m_szText,2,dLen)
- elseif '"' == charTemp then
- local s, e = string.find(m_szText, '"', 2, dLen)
- if nil ~= s and nil ~= e then
- val = val .. string.sub(m_szText,1,s)
- m_szText = string.sub(m_szText,s+1,dLen)
- else
- return nil
- end
- elseif "]" == charTemp then
- if "[" == stackOperator.temp_getBack() then
- stackOperator.popBack()
- stackItem.pushBack(val)
- val = ""
- m_szText = string.sub(m_szText,2,dLen)
- else
- return nil
- end
- elseif "," == charTemp then
- if "=" == stackOperator.temp_getBack() then
- stackOperator.popBack()
- local Item = stackItem.temp_getBack()
- Item = getVal(Item)
- stackItem.popBack()
- if nil ~= tTemp then
- tRet[Item] = tTemp
- tTemp = nil
- else
- tRet[Item] = getVal(val)
- end
- val = ""
- m_szText = string.sub(m_szText,2,dLen)
- else
- return nil
- end
- elseif "{" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- local t = doS2T()
- if nil ~= t then
- szText = sz_T2S(t)
- tTemp = t
- --val = val .. szText
- else
- return nil
- end
- elseif "}" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- return tRet
- elseif " " ~= charTemp then
- val = val .. charTemp
- m_szText = string.sub(m_szText,2,dLen)
- else
- m_szText = string.sub(m_szText,2,dLen)
- end
- end
- return tRet
- end
- local t = doS2T()
- return t
- end
- --[[
- t = {1,2,3,"sdf", a = "df", qe = 3, {7}, qq = {{2,3,a={}}}, }
- t.f = {1,2,3}
- t.m = {3,4,5}
- szT = sz_T2S(t)
- print(szT)
- print("-----------")
- tq = t_S2T(szT)
- szT = sz_T2S(tq)
- print(szT)
- --]]
- -------- 網上資料 -------------------
- function serialize(obj)
- local lua = ""
- local t = type(obj)
- if t == "number" then
- lua = lua .. obj
- elseif t == "boolean" then
- lua = lua .. tostring(obj)
- elseif t == "string" then
- lua = lua .. string.format("%q", obj)
- elseif t == "table" then
- lua = lua .. "{\n"
- for k, v in pairs(obj) do
- lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
- end
- local metatable = getmetatable(obj)
- if metatable ~= nil and type(metatable.__index) == "table" then
- for k, v in pairs(metatable.__index) do
- lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
- end
- end
- lua = lua .. "}"
- elseif t == "nil" then
- return nil
- else
- error("can not serialize a " .. t .. " type.")
- end
- return lua
- end
- function unserialize(lua)
- local t = type(lua)
- if t == "nil" or lua == "" then
- return nil
- elseif t == "number" or t == "string" or t == "boolean" then
- lua = tostring(lua)
- else
- error("can not unserialize a " .. t .. " type.")
- end
- lua = "return " .. lua
- local func = loadstring(lua)
- if func == nil then
- return nil
- end
- return func()
- end
- data = {["a"] = "a", ["b"] = "b", [1] = 1, [2] = 2, ["t"] = {1, 2, 3}}
- local sz = serialize(data)
- print(sz)
- print("---------")
- print(serialize(unserialize(sz)))
Lua裏實現將table轉成字符串(序列化)和將字符串轉換回table(反序列化)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.