Lua文件处理

原创 2008年10月03日 11:09:00
 LUPA 开源技术 > Lua > Lua文件处理

Lua文件处理

2007-07-02 13:36 来源:  网友评论 0 条 浏览次数 1687
一。文件读存:
-- 似乎不支持大文件(不能超过9k?):
function opensavetest()
   local file = io.open("c://in.lua", "r");
   if(file) then
   local data = file:read("*a"); -- i've also tried "*all" as described in PIL
   file:close();
   file = io.open("c://out.lua", "w");
   if(file) then
   file:write(data);
   file:close();
   end
   end
end
opensavetest();
 
二。非循环表格处理(见program in lua):
HERO = 1  Monster = 2  Building = 3 SumUnit = 4
cha = {}
cha[1] =
{
 basic =
  {
   Name = "农民" ,       --角色名称
   cha_type = HERO        --角色模型类型
  } ,
 Combat =
  {
     acquire = 600.00 ,       --主动攻击范围
     basic_def = 10        --基础防御
  }
}
function serialize2( o)
 if type(o) == "number" then
  g_file:write(o)
 elseif type(o) == "string" then
  g_file:write(string.format("%q", o))
 elseif type(o) == "table" then
  g_file:write("{/n")
  for k,v in pairs(o) do
   g_file:write(" [")
   serialize2(k)
   g_file:write("] = ")
   serialize2(v)
   g_file:write(",/n")
  end
  g_file:write("}/n")
 else
  error("cannot serialize a " .. type(o))
 end
end
function savetest ()
 if g_file == nil then
      print("error int 'savetest()'");
      return;
   end
 g_file:write("cha = {}/n")
 g_file:write("cha[1] = {/n")
 serialize2( cha[1] ); 
 g_file:write("}/n")
end
g_file = io.open("c://tt.lua", "w");
savetest();
g_file:close()
 
三。原program in lua中的保存带/不带循环的table
12.1.1 保存不带循环的table
我们下一个艰巨的任务是保存表。根据表的结构不同,采取的方法也有很多。没有一种单一的算法对所有情况都能很好地解决问题。简单的表不仅需要简单的算法而且输出文件也需要看起来美观。
我们第一次尝试如下:
function serialize (o)
 if type(o) == "number" then
  io.write(o)
 elseif type(o) == "string" then
  io.write(string.format("%q", o))
 elseif type(o) == "table" then
  io.write("{/n")
  for k,v in pairs(o) do
   io.write(" ", k, " = ")
   serialize(v)
   io.write(",/n")
  end
  io.write("}/n")
 else
  error("cannot serialize a " .. type(o))
 end
end
尽管代码很简单,但很好地解决了问题。只要表结构是一个树型结构(也就是说,没有共享的子表并且没有循环),上面代码甚至可以处 理嵌套表(表中表)。对于所进不整齐的表我们可以少作改进使结果更美观,这可以作为一个练习尝试一下。(提示:增加一个参数表示缩进的字符串,来进行序列 化)。前面的函数假定表中出现的所有关键字都是合法的标示符。如果表中有不符合Lua语法的数字关键字或者字符串关键字,上面的代码将碰到麻烦。一个简单 的解决这个难题的方法是将:
io.write(" ", k, " = ")
改为
io.write(" [")
serialize(k)
io.write("] = ")
这样一来,我们改善了我们的函数的健壮性,比较一下两次的结果:
-- result of serialize{a=12, b='Lua', key='another "one"'}
-- 第一个版本
{
a = 12,
b = "Lua",
key = "another /"one/"",
}
-- 第二个版本
{
["a"] = 12,
["b"] = "Lua",
["key"] = "another /"one/"",
}
我们可以通过测试每一种情况,看是否需要方括号,另外,我们将这个问题留作一个练习给大家。
12.1.2 保存带有循环的table
针对普通拓扑概念上的带有循环表和共享子表的table,我们需要另外一种不同的方法来处理。构造器不能很好地解决这种情况,我们不使用。为了表示循环我 们需要将表名记录下来,下面我们的函数有两个参数:table和对应的名字。另外,我们还必须记录已经保存过的table以防止由于循环而被重复保存。我 们使用一个额外的table来记录保存过的表的轨迹,这个表的下表索引为table,而值为对应的表名。
我们做一个限制:要保存的table只有一个字符串或者数字关键字。下面的这个函数序列化基本类型并返回结果。
function basicSerialize (o)
 if type(o) == "number" then
  return tostring(o)
 else  -- assume it is a string
  return string.format("%q", o)
 end
end
关键内容在接下来的这个函数,saved这个参数是上面提到的记录已经保存的表的踪迹的table。
function save (name, value, saved)
 saved = saved or {}   -- initial value
 io.write(name, " = ")
 if type(value) == "number" or type(value) == "string" then
  io.write(basicSerialize(value), "/n")
 elseif type(value) == "table" then
  if saved[value] then  -- value already saved?
   -- use its previous name
   io.write(saved[value], "/n")
  else
   saved[value] = name -- save name for next time
   io.write("{}/n")  -- create a new table
   for k,v in pairs(value) do -- save its fields
    local fieldname = string.format("%s[%s]", name,
           basicSerialize(k))
    save(fieldname, v, saved)
   end
  end
 else
  error("cannot save a " .. type(value))
 end
end
举个例子:
我们将要保存的table为:
a = {x=1, y=2; {3,4,5}}
a[2] = a  -- cycle
a.z = a[1]  -- shared sub-table
调用save('a', a)之后结果为:
a = {}
a[1] = {}
a[1][1] = 3
a[1][2] = 4
a[1][3] = 5
a[2] = a
a["y"] = 2
a["x"] = 1
a["z"] = a[1]
(实际的顺序可能有所变化,它依赖于table遍历的顺序,不过,这个算法保证了一个新的定义中需要的前面的节点都已经被定义过)
如果我们想保存带有共享部分的表,我们可以使用同样table的saved参数调用save函数,例如我们创建下面两个表:
a = {{"one", "two"}, 3}
b = {k = a[1]}
保存它们:
save('a', a)
save('b', b)
结果将分别包含相同部分:
a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = {}
b["k"][1] = "one"
b["k"][2] = "two"
然而如果我们使用同一个saved表来调用save函数:
local t = {}
save('a', a, t)
save('b', b, t)
结果将共享相同部分:
a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = a[1]
上面这种方法是Lua中常用的方法,当然也有其他一些方法可以解决问题。比如,我们可以不使用全局变量名来保存,即使用封包,用chunk构造一个local值然后返回之;通过构造一张表,每张表名与其对应的函数对应起来等。Lua给予你权力,由你决定如何实现。
上一篇 |

Lua从文件路径获取信息及通配符解释

Lua从文件路径获取信息及通配符解释 并举例解释 通配符 的意思
  • zhuzhuyule
  • zhuzhuyule
  • 2014年11月19日 14:55
  • 2143

LUA的异常处理

1、可以通过调用error函数显式地抛出错误,error的参数是要抛出的错误信息。 print "enter a number:" n = io.read("*number") if not...
  • hqzxsc2006
  • hqzxsc2006
  • 2014年02月27日 10:49
  • 1979

浅析lua异常捕获处理机制

异常捕获是高级语言的一大特性,通过对异常的捕获和处理,有效提高了系统的稳定性和健壮性。因为无论再怎样改进代码,都不可避免出现一些异常,例如文件io错误、网络错误、内存错误等等,就要求编码对错误进行捕获...
  • cwqcwk1
  • cwqcwk1
  • 2015年10月19日 23:13
  • 6627

时间处理_Lua语言

lua使用标准的c编写成的,所以lua具有很多c的共同性,比如占位符的使用,以及打出方式都是很一样1.如果有个为number或者是java传入的数字类型,那么如何转换为你需要使用的格式呢 ,后面参数的...
  • ONLYMETAGAIN
  • ONLYMETAGAIN
  • 2016年08月05日 14:24
  • 1187

lua中处理xml文件

lua,xml
  • zcl1804742527
  • zcl1804742527
  • 2016年09月08日 17:38
  • 107

Lua学习笔记8:文件读写

lua中文件读写经常在游戏配置中用到,比如客户端的音效音乐开关等。 Lua官方API文档:点这里 I/O库为文件操作提供4个主要函数:io.open(),io.read(),io.write...
  • xufeng0991
  • xufeng0991
  • 2014年08月09日 10:17
  • 1660

lua中过滤表情以及特殊字符

今天开发时发现,备注输入框中可以输入表情符号,然而再次展示时,却成了问号?或者直接在请求接口的时候显示数据格式不正确! 首先,这个肯定是不行的,你如果让用户输入了,并且保存成功后,但是显示的却是?,这...
  • allenjay11
  • allenjay11
  • 2016年11月17日 22:32
  • 2881

lua解析xml总结

lua解析xml有很多的第三方的库,例如:http://lua-users.org/wiki/LuaXml。但是每个库都有各自的优点和使用是否方便。 我一开始是打算使用luaXml库,在网上也找...
  • pkorochi
  • pkorochi
  • 2016年05月27日 23:37
  • 2375

使用lua实现try-catch异常捕获

lua原生并没有提供try-catch的语法来捕获异常处理,但是提供了pcall/xpcall等接口,可在保护模式下执行lua函数。因此,可以通过封装这两个接口,来实现try-catch块的捕获机制。...
  • waruqi
  • waruqi
  • 2016年12月14日 23:41
  • 4732

用lua 下载文件小示例

本文是自己闲暇之余用来学习lua的小笔记,篇幅比较短,有涉及到的例如HTTP网络协议,不细说。 本文演示的是通过HTTP 下载个远程文件,需要用到LuaSocket 库。要下载一个文件,必须先打开一...
  • yifan_lym
  • yifan_lym
  • 2015年11月02日 17:18
  • 2688
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Lua文件处理
举报原因:
原因补充:

(最多只允许输入30个字)