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 ...
随机推荐
- Openjudge-NOI题库-蛇形填充数组
题目描述 Description 用数字1,2,3,4,...,n*n这n2个数蛇形填充规模为n*n的方阵. 蛇形填充方法为: 对于每一条左下-右上的斜线,从左上到右下依次编号1,2,...,2n-1 ...
- 【转】gcc/g++ 如何支持c11 / c++11标准编译
如果用命令 g++ -g -Wall main.cpp 编译以下代码 : 1 2 3 4 5 6 7 8 9 10 11 12 /* file : main.cpp */ #include ...
- java实现线性表
/** * 线性表 * @author zyyt * */ public class LinkList {//框架级别的大师级 private int size;//链表的实际大小 private ...
- JavaScript忍者秘籍——闭包
概要:本篇博客主要介绍了JavaScript的闭包 1.闭包的工作原理 简单地说,闭包就是一个函数在创建时允许该自身函数访问并操作该自身函数之外的变量时所创建的作用域. 例如: var outerVa ...
- MediaPlayer的错误列表速查(android)
public static final int MEDIA_ERROR_IO Added in API level 17 File or network related operation error ...
- expri on the testdisk
首先,根据GNU的编译知识,来分析下载下来的目录,虽然里面有很多win的,andriod的文件,就不要管了,考入centos里面去, 按下面顺序执行就ok了. 第一步执行顺序: #autoscan ...
- Javascript 数字保留2位小数
整理使用Javascript函数将数值保留两位小数: 1.num.toFixed(2) //进位 2.(Math.round(num * 100) / 100).toFixed(2) //进位 3.( ...
- 数数字(Digit Counting,ACM/ICPC Danang 2007,UVa1225)
#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ char s[10000]; in ...
- HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...
- 仿简书分享:UIActivityViewController系统原生分享
接下来介绍UIActivityViewController: 1. 创建要分享的数据内容,加在一个数组 ActivityItems里. NSString *textToShare = @"我 ...