lua序列化实现使用的是string.dump (),关于string.dump ()的介绍,lua的API文档中写到
string.dump (function [, strip]) 返回一个包含给定函数的二进制表示(二进制块)的字符串,以便稍后对该字符串的加载将返回函数的一个副本(但带有新的upvalues)。如果strip为真值,则二进制表示可能不包含关于函数的所有调试信息,以节省空间。 带有upvalues的函数只保存upvalues的数量。当(重新)加载时,这些upvalues将接收包含nil的新实例。(您可以使用debug库以适合您需要的方式序列化和重新加载函数的upvalue。)
通俗点就是在讲string.dump有两个参数,第一个参数传入序列化的函数名,第二个参数要传入的是boolean值(该值为真,则序列化函数时不会包含函数的调试信息,以节省空间)这个参数为真为假我都没看出什么区别,load序列化之后的函数调用中,debug照样能打印出来,
举个例子
- 序列化 使用IO读取一个lua文件存入变量data,然后序列化loadstring之后的函数,伪代码如下:
dumpData=string.dump(loadstring(data)) io.open(path,“wb”):write(dumpData)
- 反序列化 上面我们把序列化返回的二进制数据写入文件,下次直接读取二进制数据,再使用loadstring或load方法反序列化成函数(这个我是这么理解的),伪代码如下:
data=io.open(path,“rb”):read("*a") dumpfunc=loadstring(data)
实际代码演示: 要序列化的文件如下
代码语言:javascript复制--[[
ModuleName : dumpfile.lua
Path : E:SluaNetProtolsrctestdumpfile.lua
Author : jinbo
CreateTime : 2020-05-15 10:05:02
Description :
--]]
local module={}
function Start()
print("Dump file Start function Execute")
print(debug.getinfo(1,"n").name)
end
function Add(a,b)
print("Input a=",a)
print("Input b=",b)
print("return a b=",a b)
return a b
end
function ShowMsg(msg)
print(msg)
end
function module.Main()
print("module.Main is Executed")
end
return module
序列化与反序列化操作代码如下:
代码语言:javascript复制--[[
ModuleName : dumpTest.lua
Path : E:SluaNetProtolsrctestdumpTest.lua
Author : jinbo
CreateTime : 2020-05-15 10:04:07
Description :
--]]
local file=io.open("E:/SluaNetProtol/src/test/dumpfile.lua","rb")
local data=file:read("*a")
file:close()
local dumpFunc=loadstring(data,"dumpfile.lua")
-----------test Start-----------------------
-- local module=dumpFunc()
-- module.Main()
-----------test End-----------------------
local dumpData=string.dump(dumpFunc,false)
local wfile=io.open("E:/SluaNetProtol/src/test/dumpfile.txt","wb")
wfile:write(dumpData)
wfile:close()
------------Read dumpData and Execute-------------------------
local rfile=io.open("E:/SluaNetProtol/src/test/dumpfile.txt","rb")
local rData=rfile:read("*a")
rfile:close()
local loadFunc=loadstring(rData)
local newEnv={}
setfenv(loadFunc,newEnv)()
setmetatable(newEnv,{__index=_G})
newEnv.Start()
newEnv.Add(2,3)
newEnv.ShowMsg("this is a test function")
print(newEnv.module)
结果显示能够执行反序列化之后的函数: