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)
实际代码演示:
要序列化的文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | --[[ ModuleName : dumpfile.lua Path : E:\SluaNetProtol\src\test\dumpfile.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 |
序列化与反序列化操作代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | --[[ ModuleName : dumpTest.lua Path : E:\SluaNetProtol\src\test\dumpTest.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) |
结果显示能够执行反序列化之后的函数:
