Lua:开源库 lua-cjson 安装及使用

Lua:开源库 lua-cjson 安装及使用

开源库 lua-cjson 是一个简单小巧的动态库,可被 lua 脚本 require 加载。

在 Lua 中通过一系列的 lua-cjson API 调用完成 Lua 值与 Json 值的相互转换(编码及解码)。

注:lua-cjson 要求编码格式为UTF8。lua-cjson 不支持 UTF-16 and UTF-32。


安装:

Step 1:安装 Lua 环境:

上传 Lua 源码 lua-5.3.5.tar.gz 到用户主目录($HOME)下,解压缩,获得 lua-5.3.5 目录。

修改 $HOME/lua-5.3.5/Makefile 文件:

编译 && 安装:

cd $HOME/lua-5.3.5/ && make linux && make install

安装完毕:

Step 2:安装 lua-cjson 库:

上传 lua-cjson 源码 lua-cjson-2.1.0.tar.gz 到用户主目录($HOME)下,解压缩,获得 lua-cjson-2.1.0 目录。

修改 $HOME/lua-cjson-2.1.0/Makefile 文件:

编译 && 安装:

cd $HOME/lua-cjson-2.1.0/ && make && make install

安装完毕:


使用:
编码:
local cjson = require "cjson"

-- 创建实例
local cjson2 = cjson.new()

-- 布尔类型
local lua_bool = true
print(cjson2.encode(lua_bool))

-- 数组类型
local lua_array = {1, 2, 3, 4, 5, 6}
print(cjson2.encode(lua_array))

-- 数值类型
local lua_number = 6.66
print(cjson2.encode(lua_number))

-- 字符串类型
local lua_string = "I am test1280"
print(cjson2.encode(lua_string))

-- 对象类型
local lua_object = {
    ["name"] = "Jiang",
    ["age"] = 24,
    ["addr"] = "BeiJing",
    ["email"] = "1569989xxxx@126.com",
    ["tel"] = "1569989xxxx"
}
print(cjson2.encode(lua_object))

执行 lua 脚本:

LUA_CPATH=$HOME/lua/lib/lua/5.1/?.so lua lua2json.lua

解码:
local cjson = require "cjson"

-- 创建实例
local cjson2 = cjson.new()

-- 布尔类型
local json_bool = "false"
local lua_bool = cjson2.decode(json_bool)
print(type(lua_bool))

-- 数组类型
local json_array = "[9, 8, 7, 6, 5, 4, 3, 2, 1]"
local lua_array = cjson2.decode(json_array)
print(type(lua_array))
--[[
for k, v in ipairs(lua_array) do
    print("k = " .. k)
    print("v = " .. v)
end
--]]

-- 数值类型
local json_number = "666.666"
local lua_number = cjson2.decode(json_number)
print(type(lua_number))
--[[
print(lua_number)
--]]

-- 字符串类型
local json_string = "\"I am test1280\""
local lua_string = cjson2.decode(json_string)
print(type(lua_string))
--[[
print(lua_string)
--]]

-- 对象类型
local json_object = "{\"name\":\"Jiang\",\"addr\":\"BeiJing\",\"age\":24,\"tel\":\"1569989xxxx\",\"email\":\"1569989xxxx@126.com\"}"
local lua_object = cjson2.decode(json_object)
print(type(lua_object))
--[[
for k, v in pairs(lua_object) do
    print("k = " .. k)
    print("v = " .. v)
end
--]]

执行 lua 脚本:

LUA_CPATH=$HOME/lua/lib/lua/5.1/?.so lua json2lua.lua

注:

1)LUA_CPATH=$HOME/lua/lib/lua/5.1/?.so lua

将 LUA_CPATH 作为环境变量传入 lua 进程环境表,以便 lua 在执行 require 函数时可以知道从哪里 dlopen 这个动态库。

当然,没必要一定写到命令行中,完全可以写到 $HOME/.bash_profile 中,export LUA_CPATH。


上面的示例代码中使用了两个 API:cjson.encode and cjson.decode。

cjson.encode 是用于编码,将 lua 值转换为 json 字符串;
cjson.decode 是用于解码,将 json 字符串转换为 lua 值;

除了这两个 API,还有以下 API 可以使用:

encode_sparse_array
encode_max_depth
decode_max_depth
encode_number_precision
encode_keep_buffer
encode_invalid_numbers
decode_invalid_numbers
new

上面的示例中也有使用到 new 接口:

cjson.new can be used to instantiate an independent copy of the Lua CJSON module.
The new module has a separate persistent encoding buffer, and default settings.

可以通过 new 接口创建一个 cjson 实例对象,此对象含有独立的编解码缓冲区以及独立的配置参数表。

如果多个线程同时对同一个 cjson 实例对象调用编解码操作,结果是不可预估的。

因为多个线程本质上对同时对同一编解码缓冲区进行了读写操作。

所以,不同线程应当串行操作同一个 cjson 实例对象 或 并行操作互不相同的 cjson 实例对象(不同的编解码缓冲区)。

Lua CJSON can support Lua implementations using multiple preemptive threads within a single Lua state provided the persistent encoding buffer is not shared.

This can be achieved by one of the following methods:

Disabling the persistent encoding buffer with cjson.encode_keep_buffer

Ensuring each thread calls cjson.encode separately (ie, treat cjson.encode as non-reentrant).

Using a separate cjson module table per preemptive thread (cjson.new)

lua-cjson 提供一些 API 以修改 cjson 实例对象的参数表默认配置,来影响 cjson 实例对象在编码解码时的行为过程。

例如,可以通过 encode_max_depth 和 decode_max_depth 来更改编解码时的最大嵌套深度,等等。


关于 lua-cjson cjson.encode 序列化 Lua 值的一点问题

local cjson = require "cjson"
local cjson2 = cjson.new()
local array = {}
array[1] = 1 
array[6] = 6 
array[9] = 9
print(cjson2.encode(array))

执行结果为:

[1,null,null,null,null,6,null,null,9]

当存在某 key-value 对且 key 类型不是 number 类型:

local cjson = require "cjson"
local cjson2 = cjson.new()
local array = {}
array[1] = 1
array[6] = 6
array[9] = 9
array["name"] = "test1280"  -- 注意此行
print(cjson2.encode(array))

执行结果为:

{"1":1,"9":9,"6":6,"name":"test1280"}

原因在于:

Lua CJSON uses a heuristic to determine whether to encode a Lua table as a JSON array or an object.

A Lua table with only positive integer keys of type number will be encoded as a JSON array.

All other tables will be encoded as a JSON object.

另外,cjson.encode 不会触发元方法:

Lua CJSON does not use metamethods when serialising tables.

rawget is used to iterate over Lua arrays

next is used to iterate over Lua objects

以及,若待转换的 Lua table 中的 key 有非 number 且非 string 类型值,则转换时报错:

JSON object keys are always strings.

Hence cjson.encode only supports table keys which are type number or string.

All other types will generate an error.

在 cjson.encode 时,由于待转换 Lua table 不符合转换要求可能引发一些错误:

By default, encoding the following Lua values will generate errors:

Numbers incompatible with the JSON specification (infinity, NaN)

Tables nested more than 1000 levels deep

Excessively sparse Lua arrays

我们可以通过一些 lua-cjson 提供的 API,修改 cjson 实例对象默认参数值,使得在 encode 时行为改变:

cjson.encode_invalid_numbers

cjson.encode_max_depth

cjson.encode_sparse_array


参考文档:

1.https://www.kyne.com.au/~mark/software/lua-cjson-manual.html#encode_max_depth

代码下载:

1.https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz

2.https://www.kyne.com.au/~mark/software/lua-cjson.php

3.https://github.com/mpx/lua-cjson/

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值