Lua里实现将table转成字符串(序列化)和将字符串转换回table(反序列化)

来源:互联网 发布:淘宝退款什么时候到账 编辑:程序博客网 时间:2024/05/16 06:16

  1. --[[  
  2.  file name :    table序列化和反序列化的问题.lua  
  3.  author  :      Clark/陈泽丹  
  4.  created :      2011-12-22  
  5.  备注:  
  6.  支持table的递归结构,但数据类型不支持function属性(因为function只是记录地址,在不同机器上序列化和反序列化后的地址相同没什么意义)  
  7.    
  8.  后记:    
  9.  郁闷, 写完到网上一搜, 才发现原来Lua有提供一些现成的函数可用来做序列化和反序列化操作。。。    
  10.  其中loadstring可以执行字符串。    
  11.  通过    
  12.  lua = "return " .. lua    
  13.  local func = loadstring(lua)    
  14.  即实现了反序列化。。。  
  15. --]]  
  16.   
  17.   
  18.   
  19. ----------- 个人编写 -----------------  
  20.   
  21. --table转字符串(只取标准写法,以防止因系统的遍历次序导致ID乱序)  
  22. function sz_T2S(_t)  
  23.     local szRet = "{"  
  24.     function doT2S(_i, _v)  
  25.         if "number" == type(_i) then  
  26.             szRet = szRet .. "[" .. _i .. "] = "  
  27.             if "number" == type(_v) then  
  28.                 szRet = szRet .. _v .. ","  
  29.             elseif "string" == type(_v) then  
  30.                 szRet = szRet .. '"' .. _v .. '"' .. ","  
  31.             elseif "table" == type(_v) then  
  32.                 szRet = szRet .. sz_T2S(_v) .. ","  
  33.             else  
  34.                 szRet = szRet .. "nil,"  
  35.             end  
  36.         elseif "string" == type(_i) then  
  37.             szRet = szRet .. '["' .. _i .. '"] = '  
  38.             if "number" == type(_v) then  
  39.                 szRet = szRet .. _v .. ","  
  40.             elseif "string" == type(_v) then  
  41.                 szRet = szRet .. '"' .. _v .. '"' .. ","  
  42.             elseif "table" == type(_v) then  
  43.                 szRet = szRet .. sz_T2S(_v) .. ","  
  44.             else  
  45.                 szRet = szRet .. "nil,"  
  46.             end  
  47.         end  
  48.     end  
  49.     table.foreach(_t, doT2S)  
  50.     szRet = szRet .. "}"  
  51.     return szRet  
  52. end  
  53.   
  54.   
  55.   
  56. --字符串转table(反序列化,异常数据直接返回nil)  
  57. function t_S2T(_szText)  
  58.     --栈  
  59.     function stack_newStack()  
  60.         local first = 1  
  61.         local last = 0  
  62.         local stack = {}  
  63.         local m_public = {}  
  64.         function m_public.pushBack(_tempObj)  
  65.             last = last + 1  
  66.             stack[last] = _tempObj  
  67.         end  
  68.         function m_public.temp_getBack()  
  69.             if m_public.bool_isEmpty() then  
  70.                 return nil  
  71.             else  
  72.                 local val = stack[last]  
  73.                 return val  
  74.             end  
  75.         end  
  76.         function m_public.popBack()  
  77.             stack[last] = nil  
  78.             last = last - 1  
  79.         end  
  80.         function m_public.bool_isEmpty()  
  81.             if first > last then  
  82.                 first = 1  
  83.                 last = 0  
  84.                 return true  
  85.             else  
  86.                 return false  
  87.             end  
  88.         end  
  89.         function m_public.clear()  
  90.             while false == m_public.bool_isEmpty() do  
  91.                 stack.popFront()  
  92.             end  
  93.         end  
  94.         return m_public  
  95.     end  
  96.     function getVal(_szVal)  
  97.         local s, e = string.find(_szVal,'"',1,string.len(_szVal))  
  98.         if nil ~= s and nil ~= e then  
  99.             --return _szVal  
  100.             return string.sub(_szVal,2,string.len(_szVal)-1)  
  101.         else  
  102.             return tonumber(_szVal)  
  103.         end  
  104.     end  
  105.   
  106.     local m_szText = _szText  
  107.     local charTemp = string.sub(m_szText,1,1)  
  108.     if "{" == charTemp then  
  109.         m_szText = string.sub(m_szText,2,string.len(m_szText))  
  110.     end  
  111.     function doS2T()  
  112.         local tRet = {}  
  113.         local tTemp = nil  
  114.         local stackOperator = stack_newStack()  
  115.         local stackItem = stack_newStack()  
  116.         local val = ""  
  117.         while true do  
  118.             local dLen = string.len(m_szText)  
  119.             if dLen <= 0 then  
  120.                 break  
  121.             end  
  122.   
  123.             charTemp = string.sub(m_szText,1,1)  
  124.             if "[" == charTemp or "=" == charTemp then  
  125.                 stackOperator.pushBack(charTemp)  
  126.                 m_szText = string.sub(m_szText,2,dLen)  
  127.             elseif '"' == charTemp then  
  128.                 local s, e = string.find(m_szText, '"', 2, dLen)  
  129.                 if nil ~= s and nil ~= e then  
  130.                     val = val .. string.sub(m_szText,1,s)  
  131.                     m_szText = string.sub(m_szText,s+1,dLen)  
  132.                 else  
  133.                     return nil  
  134.                 end  
  135.             elseif "]" == charTemp then  
  136.                 if "[" == stackOperator.temp_getBack() then  
  137.                     stackOperator.popBack()  
  138.                     stackItem.pushBack(val)  
  139.                     val = ""  
  140.                     m_szText = string.sub(m_szText,2,dLen)  
  141.                 else  
  142.                     return nil  
  143.                 end  
  144.             elseif "," == charTemp then  
  145.                 if "=" == stackOperator.temp_getBack() then  
  146.                     stackOperator.popBack()  
  147.                     local Item = stackItem.temp_getBack()  
  148.                     Item = getVal(Item)  
  149.                     stackItem.popBack()  
  150.                     if nil ~= tTemp then  
  151.                         tRet[Item] = tTemp  
  152.                         tTemp = nil  
  153.                     else  
  154.                         tRet[Item] = getVal(val)  
  155.                     end  
  156.                     val = ""  
  157.                     m_szText = string.sub(m_szText,2,dLen)  
  158.                 else  
  159.                     return nil  
  160.                 end  
  161.             elseif "{" == charTemp then  
  162.                 m_szText = string.sub(m_szText,2,string.len(m_szText))  
  163.                 local t = doS2T()  
  164.                 if nil ~= t then  
  165.                     szText = sz_T2S(t)  
  166.                     tTemp = t  
  167.                     --val = val .. szText  
  168.                 else  
  169.                     return nil  
  170.                 end  
  171.             elseif "}" == charTemp then  
  172.                 m_szText = string.sub(m_szText,2,string.len(m_szText))  
  173.                 return tRet  
  174.             elseif " " ~= charTemp then  
  175.                 val = val .. charTemp  
  176.                 m_szText = string.sub(m_szText,2,dLen)  
  177.             else  
  178.                 m_szText = string.sub(m_szText,2,dLen)  
  179.             end  
  180.         end  
  181.         return tRet  
  182.     end  
  183.     local t = doS2T()  
  184.     return t  
  185. end  
  186.   
  187. --[[  
  188. t = {1,2,3,"sdf", a = "df", qe = 3, {7}, qq = {{2,3,a={}}}, }  
  189. t.f = {1,2,3}  
  190. t.m = {3,4,5}  
  191. szT = sz_T2S(t)  
  192. print(szT)  
  193. print("-----------")  
  194. tq = t_S2T(szT)  
  195. szT = sz_T2S(tq)  
  196. print(szT)  
  197. --]]  
  198.   
  199.   
  200. -------- 网上资料 -------------------  
  201.   
  202.   
  203.   
  204. function serialize(obj)  
  205.     local lua = ""  
  206.     local t = type(obj)  
  207.     if t == "number" then  
  208.         lua = lua .. obj  
  209.     elseif t == "boolean" then  
  210.         lua = lua .. tostring(obj)  
  211.     elseif t == "string" then  
  212.         lua = lua .. string.format("%q", obj)  
  213.     elseif t == "table" then  
  214.         lua = lua .. "{\n"  
  215.     for k, v in pairs(obj) do  
  216.         lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  217.     end  
  218.     local metatable = getmetatable(obj)  
  219.         if metatable ~= nil and type(metatable.__index) == "table" then  
  220.         for k, v in pairs(metatable.__index) do  
  221.             lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  222.         end  
  223.     end  
  224.         lua = lua .. "}"  
  225.     elseif t == "nil" then  
  226.         return nil  
  227.     else  
  228.         error("can not serialize a " .. t .. " type.")  
  229.     end  
  230.     return lua  
  231. end  
  232.   
  233. function unserialize(lua)  
  234.     local t = type(lua)  
  235.     if t == "nil" or lua == "" then  
  236.         return nil  
  237.     elseif t == "number" or t == "string" or t == "boolean" then  
  238.         lua = tostring(lua)  
  239.     else  
  240.         error("can not unserialize a " .. t .. " type.")  
  241.     end  
  242.     lua = "return " .. lua  
  243.     local func = loadstring(lua)  
  244.     if func == nil then  
  245.         return nil  
  246.     end  
  247.     return func()  
  248. end  
  249.   
  250. data = {["a"] = "a", ["b"] = "b", [1] = 1, [2] = 2, ["t"] = {1, 2, 3}}  
  251. local sz = serialize(data)  
  252. print(sz)  
  253. print("---------")  
  254. print(serialize(unserialize(sz)))  

http://blog.csdn.net/xiaodan007/article/details/7096718


0 0
原创粉丝点击