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 数据文件的更多相关文章

  1. [APUE]系统数据文件与信息

    一.口令文件 UNIX口令文件包含下表中的各个字段,这些字段包含在 由于历史原因,口令文件是/bin/passwd,而且是一个文本文件,每一行都包括了上表中的七个字段,字段之间用":&quo ...

  2. U盘存放大于4G数据文件且无须格式化U盘的解决方法

    现在优盘的容量越来越大了,价格越来越便宜,可是它也有个缺点,因为它默认的文件系统是"FAT32",这种文件系统最大只能保存4G的文件,超过4G的文件就不能保存在优盘上了,这样就不能 ...

  3. ORACLE 移动数据文件 控制文件 重做日志文件

    ORACLE数据库有时候需要对存储进行调整,增加分区.IO调优等等,此时需要移动数据文件.重做日志文件.控制文件等等,下文结合例子总结一下这方面的知识点. 进行数据文件.重做日志文件.控制文件的迁移前 ...

  4. SQL SERVER 监控数据文件增长情况

    在项目前期评估数据库的增长情况,然后根据数据库数据量的增长情况来规划存储的分配其实是一件比较麻烦的事情.因为项目没有上线,用什么来评估数据库的数据增长情况呢? 如果手头没有实际的数据,我们只能从表的数 ...

  5. 测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程

    测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程 最近系统出现问题,由于数据库产生的日志量太大无法开启归档模式,导致offline的 ...

  6. 破解Outlook数据文件密码/PST访问密码

    不少人会经常用outlook,邮件多的时候可能不定期导出一个PST文件,为安全起见,给PST文件设置访问密码,可是时间长了,难免忘记,怎么办呢?不用担心,你自己就可以解决,无论是Outlook97.O ...

  7. oracle 11g dbf数据文件从C盘迁移到D盘

    服务器系统为 windows 2008 R2 64位,由于C盘空间将满,要将C盘的oracle的DBF数据文件迁移到D盘下,步骤如下: 1.输入cmd,启动 cmd.exe窗口 2.输入 sqlplu ...

  8. oracle数据文件不小心被删除,导致对应的表空间删不掉的处理方法

    问题现象:数据文件被无意删除,导致数据库表空间无法删除,并且重新刷表空间提示表空间已经存在:解决方法:1.oracle用户登录服务器,使用sysdba连接数据库 >sqlplus / as sy ...

  9. [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)

    <Windows Azure Platform 系列文章目录> 之前的内容里,我介绍了如何将本地的Server 2012中文版 VHD上传至Windows Azure,并创建基于该Serv ...

随机推荐

  1. python reduce使用实例

    通过一个简单的算法来了解reduce的巧用. 构建函数persistence(n),如果n>9,则返回0.否则继续根据n的权重来分解n,如n=999,则分解为9,9,9.那么将9*9*9=729 ...

  2. 49、word2vec - tensorflow

    Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32Type & ...

  3. 淘宝npm镜像使用方法

    镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 通过config命令npm config set registry https://registry. ...

  4. python 之文本搜索与替换文件中的文本

    #!/usr/local/env python import os, sys nargs = len(sys.argv) if not 3 <= nargs <= 5: print &qu ...

  5. uitextfield银行卡加空格

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementS ...

  6. 366. Find Leaves of Binary Tree C#

    Example:Given binary tree 1 / \ 2 3 / \ 4 5 Returns [4, 5, 3], [2], [1]. Explanation: 1. Removing th ...

  7. 防范XSS

    .net framework4.5 提供了AntiXss类,来防范XSS攻击. 在开放指令的同时过滤危险字符串,使用AntiXss.GetSafeHtmlFragment(html)方法,具体可以参照 ...

  8. BT 的相关资料

    1.Android中bluetooth的架构 http://blog.csdn.net/u011960402/article/details/11035947 2.Android4.0中Bluetoo ...

  9. c++ inline关键字的理解

    1. inline是实现修饰符,而非声明修饰符,所以应该用于实现部分的修饰(你也可以放置inline在声明,但是没有必要) 2. 所有中类中定义的函数都默认声明为inline函数,所有我们不用显示地去 ...

  10. 不同浏览器对URL最大长度的限制

    不同浏览器对URL最大长度的限制   1.今天碰到一个bug,window.open后面的页面,接收参数不全,导致后台报错.实验了一下.发现是使用get方法请求服务器时,URL过长所致 微软官方的说明 ...