Lua序列化

一、Lua序列化

序列化通俗一点的解释,就是将数据对象转换为字节流再通过IO输出到文件或者网络,读取的时候再将这些数据重新构造为与原始对象具有相同值得新对象。

我们经常需要序列化一些数据,为了将数据转换为字节流或者字符流,这样我们就可以保存到文件或者通过网络发送出去。我们可以在Lua代码中描述序列化的数据,在这种方式下,我们运行读取程序即可从代码中构造出保存的值。

通常,我们使用这样的方式varname = <exp>来保存一个全局变量的值。varname部分比较容易理解,下面我们来看看如何写一个产生值的代码。对于一个数值来说:
在这里插入图片描述

对于字符串值而言,原始的写法应该是:
在这里插入图片描述

然而,如果字符串包含特殊字符(比如引号或者换行符),产生的代码将不是有效的Lua程序。这时候你可能用下面方法解决特殊字符的问题:
在这里插入图片描述
千万不要这样做!双引号是针对手写的字符串的而不是针对自动产生的字符串。如果有人恶意的引导你的程序去使用" ]]..os.execute('rm *')..[[ "这样的方式去保存某些东西(比如它可能提供字符串作为地址)你最终的chunk将是这个样子:
在这里插入图片描述
如果你load这个数据,运行结果可想而知的。为了以安全的方式引用任意的字符串,string标准库提供了格式化函数专门提供"%q"选项。它可以使用双引号表示字符串并且可以正确的处理包含引号和换行等特殊字符的字符串。这样一来,我们的序列化函数可以写为:
在这里插入图片描述

二、保存不带循环的table

我们下一个艰巨的任务是保存表。根据表的结构不同,采取的方法也有很多。没有一种单一的算法对所有情况都能很好地解决问题。简单的表不仅需要简单的算法而且输出文件也需要看起来美观。

我们第一次尝试如下:
在这里插入图片描述
尽管代码很简单,但很好地解决了问题。只要表结构是一个树型结构(也就是说,没有共享的子表并且没有循环),上面代码甚至可以处理嵌套表(表中表)。对于所进不整齐的表我们可以少作改进使结果更美观,这可以作为一个练习尝试一下。(提示:增加一个参数表示缩进的字符串,来进行序列化)。

前面的函数假定表中出现的所有关键字都是合法的标示符。如果表中有不符合Lua语法的数字关键字或者字符串关键字,上面的代码将碰到麻烦。一个简单的解决这个难题的方法是将:
在这里插入图片描述
这样一来,我们改善了我们的函数的健壮性,比较一下两次的结果:
在这里插入图片描述
我们可以通过测试每一种情况,看是否需要方括号。

不带方括号:
在这里插入图片描述
结果如下:
在这里插入图片描述

带方括号:
在这里插入图片描述
结果如下:
在这里插入图片描述
可以看出结果两种方法都行。

三、保存带有循环的table

针对普通拓扑概念上的带有循环表和共享子表的table,我们需要另外一种不同的方法来处理。构造器不能很好地解决这种情况,我们不使用。为了表示循环我们需要将表名记录下来,下面我们的函数有两个参数:table和对应的名字。另外,我们还必须记录已经保存过的table以防止由于循环而被重复保存。我们使用一个额外的table来记录保存过的表的轨迹,这个表的下表索引为table,而值为对应的表名。

我们做一个限制:要保存的table只有一个字符串或者数字关键字。下面的这个函数序列化基本类型并返回结果。
在这里插入图片描述
关键内容在接下来的这个函数,saved这个参数是上面提到的记录已经保存的表的踪迹的table。
在这里插入图片描述

举个例子:

我们将要保存的table为:
在这里插入图片描述

完整代码:
在这里插入图片描述
输出结果 :
在这里插入图片描述
(实际的顺序可能有所变化,它依赖于table遍历的顺序,不过,这个算法保证了一个新的定义中需要的前面的节点都已经被定义过)

如果我们想保存带有共享部分的表,我们可以使用同样tablesaved参数调用save函数,例如我们创建下面两个表:
在这里插入图片描述
保存它们:
在这里插入图片描述
结果将分别包含相同部分:
在这里插入图片描述

然而如果我们使用同一个saved表来调用save函数
在这里插入图片描述
结果将共享相同部分:
在这里插入图片描述
上面这种方法是Lua中常用的方法,当然也有其他一些方法可以解决问题。比如,我们可以不使用全局变量名来保存,即使用封包,用chunk构造一个local值然后返回之;通过构造一张表,每张表名与其对应的函数对应起来等。Lua给予你权力,由你决定如何实现。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森明帮大于黑虎帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值