chapter 12_1 数据文件
Lua的一个重要特性,就是可以作为配置文件,利用到table构造式来定义一种文件格式。
只需要在写数据时做一点额外的工作,读取数据就会变得相当容易。也就是将数据作为Lua代码输出。
当运行这些代码时,程序也就读取了数据。而table的构造式可以使这些输出代码看上去更像是一个普通的数据文件。
如果是为了应用而创建数据文件的话,那么就可以使用Lua的构造式作为格式。在这种格式中,每条数据记录表示为
一个Lua构造式:
local mode = {}
function Module(b)
if b.name then
mode[b.name] = b
end
end dofile("data") ---[[ data 文件
Module{
name = "video",
frame_rate = ,
frame_type = "H264",
frame_bitrate = ,
frame_interval = ,
frame_control = "vbr", -- cbr
} Module{
name = "audio",
audio_type = "acc",
sampling_rate = , --采样率
audio_channel = "stereo", --立体声
}
Module{<code>}与Module({<code>})是完全等价的,都是以一个table作为参数来调用Module函数。
因此,上面的这段数据也是一个Lua程序。为了读取该文件,我们只需要定义一个合适的Module,然后运行就可以了。
这种格式就是“自描述的数据”格式,其中每项数据都伴随一个表示其含义的简短描述。比CSV或其他紧缩格式更具可读性。
当需要修改时,可以在基本格式中作一个细小的改动,而不需要同时改变数据文件。
例如要新增一个字段,只需修改读取程序中的一小块就可以了,内容就是当该字段不存在时提供一个默认值。
使用名值对格式,可以打印收集mode的程序:
for name in pairs(mode) do
print (name)
end
Lua不仅运行速度快,而且编译速度也快。
自从Lua创建之处就把数据描述作为Lua的主要应用之一来考虑。
串行化
通常需要串行化一些数据,也就是将数据转换为一个字节流或字符流。然后就可以将其存储到一个文件中,或者通过
网络连接发送出去。串行化后的数据可以用Lua代码来表示,这样当运行这些代码时,存储的数据就可以在读取程序中得到重构。
如果想要恢复一个全局变量的值,那么串行化的结果或许可以是"varname = <exp>",其中<exp>是一段用于创建该值得Lua代码。
而varname只是一个简单的标识符。
下面演示如何编写创建一个值的代码,例如对于一个数字值,方法如下:
function serialize(o)
if type(o) == "number" then
io.write(string.format("%a",o))
else
<other cases>
end
end
对于一个字符串值,方法如下:
if type(o) == "string" then
io.write("'",o,"'")
如果字符串包括特殊字符(引号或者换行符),那么最终代码就不是一段有效的Lua程序了。
但是可以使用另一种方法:
if type(o) == "string" then
io.write("[[ ",o,"]] ")
注意,如果恶意的用户故意使其字符串为" ]] .. os.execute('rm *').. [[ ",那么最终保存下来的结果变成:
varname = [[ ]] .. os.execute('rm *').. [[]]
如果加载这个数据,将会出现不可估量的后果。
一个简单的办法:用“%q”来使用string.format函数。这样它就会用双引号来括住字符串,并且正确地转移其中的双引号和换行符。
a = 'a "problematic" \\string'
print(string.format("%q",a)) --> "a \"problemmatic\" \\string"
通过这个特性,serialize函数可以改为:
function serialize(o)
if type(o) == "number" then
io.write(o)
elseif type(o) == "string" then
io.write(string.format("%q",o))
else
<other cases>
end
end
Lua5.1还提供了另一种可以以一种安全的方法来括住任意字符串的方法。
用“[=[ ... ]=]” 标记长字符串。这种方式主要是为手写的代码提供方便的,通过它就不需要改变任何字符串的内容了。
在自动生成的代码中,要转移那些问题字符,还是使用string.format与“%q”选项更为方便。
chapter 12_1 数据文件的更多相关文章
- [APUE]系统数据文件与信息
一.口令文件 UNIX口令文件包含下表中的各个字段,这些字段包含在 由于历史原因,口令文件是/bin/passwd,而且是一个文本文件,每一行都包括了上表中的七个字段,字段之间用":&quo ...
- U盘存放大于4G数据文件且无须格式化U盘的解决方法
现在优盘的容量越来越大了,价格越来越便宜,可是它也有个缺点,因为它默认的文件系统是"FAT32",这种文件系统最大只能保存4G的文件,超过4G的文件就不能保存在优盘上了,这样就不能 ...
- ORACLE 移动数据文件 控制文件 重做日志文件
ORACLE数据库有时候需要对存储进行调整,增加分区.IO调优等等,此时需要移动数据文件.重做日志文件.控制文件等等,下文结合例子总结一下这方面的知识点. 进行数据文件.重做日志文件.控制文件的迁移前 ...
- SQL SERVER 监控数据文件增长情况
在项目前期评估数据库的增长情况,然后根据数据库数据量的增长情况来规划存储的分配其实是一件比较麻烦的事情.因为项目没有上线,用什么来评估数据库的数据增长情况呢? 如果手头没有实际的数据,我们只能从表的数 ...
- 测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程
测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程 最近系统出现问题,由于数据库产生的日志量太大无法开启归档模式,导致offline的 ...
- 破解Outlook数据文件密码/PST访问密码
不少人会经常用outlook,邮件多的时候可能不定期导出一个PST文件,为安全起见,给PST文件设置访问密码,可是时间长了,难免忘记,怎么办呢?不用担心,你自己就可以解决,无论是Outlook97.O ...
- oracle 11g dbf数据文件从C盘迁移到D盘
服务器系统为 windows 2008 R2 64位,由于C盘空间将满,要将C盘的oracle的DBF数据文件迁移到D盘下,步骤如下: 1.输入cmd,启动 cmd.exe窗口 2.输入 sqlplu ...
- oracle数据文件不小心被删除,导致对应的表空间删不掉的处理方法
问题现象:数据文件被无意删除,导致数据库表空间无法删除,并且重新刷表空间提示表空间已经存在:解决方法:1.oracle用户登录服务器,使用sysdba连接数据库 >sqlplus / as sy ...
- [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)
<Windows Azure Platform 系列文章目录> 之前的内容里,我介绍了如何将本地的Server 2012中文版 VHD上传至Windows Azure,并创建基于该Serv ...
随机推荐
- 安装oracle 10g时提示:操作系统版本: 必须是5.1或者5.2 怎么办?
1.在安装目录中搜索refhost.xml,然后在适当位置添加以下内容,注意括号配对 <!--Microsoft Windows 7--> <OPERATING_SYSTEM> ...
- Unity人工智能学习—确定性AI算法之追踪算法一
转自http://blog.csdn.net/zhangxiao13627093203/article/details/47451063 尽管随机运动可能完全不可预知,它还是相当无趣的,因为它完全是以 ...
- SpannableString可以被点击的文字
1 TextView tv= (TextView) findViewById(R.id.textview_z); String text="一段可以被点击点击的文字,文字可以变成图片&quo ...
- transient关键字小结
java中实现序列化有两种实现方式,一种是自动的,只要实现Serilizable接口,另一种是需要手动指定需要序列化的成员变量,实现Externalizable接口. transient的特点: 1. ...
- java中float和double的区别
float表示单精度浮点数在机内占4个字节,用32位二进制描述. double表示双精度浮点数在机内占8个字节,用64位二进制描述.浮点数在机内用指数型式表示,分解为:数符,尾数,指数符,指数四部分. ...
- [Rails] 从 Request 到 Response(2)
本文翻译自:Rails from Request to Response 系列:个人选择了自己感兴趣的部分进行翻译,需要阅读原文的同学请戳前面的链接. 第二部分 路由(Routing) Blog::A ...
- jquery事件绑定
window.onload 和 Jquery $(document).ready() 区别 * .用JavaScript的方式window.onload :必须等页面上所有的元素(css/js/图片) ...
- shell中$(( )) 与 $( ) 还有${ }的区别
http://blog.chinaunix.net/uid-14351756-id-2820651.html $( ) 与 ` ` (反引号)在 bash shell 中,$( ) 与 ` ` (反引 ...
- 模仿快递路线图的html, css 样式
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- IIS下访问网络驱动器(网络位置)
System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = "cmd.ex ...