Unity JSON编码解码之LitJson 深度剖析
JSON在游戏开发中是一种序列化/反序列化常用的技术,把游戏相关的象源析数据,如地图组成,码解通过JSON编码,对象的原序列化成JSON文本,转对n转传输或存储,象源析源码核心类型要使用的码解时候再通过JSON技术把文本解析成数据对象,在代码中使用。对象的原本文将从以下几个方面详细的转对n转深度剖析JSON与LitJson库的编码解码:
对,这里有一个游戏开发交流小组,象源析希望大家可以点击进来一起交流一下开发经验呀
(1)什么是码解JSON;
(2)Unity如何使用LitJson;
(3)LitJson核心源码分析;
1: 什么是JSON
JSON(JavaScriptObject Notation, JS对象简谱)是一种轻量级的数据交换格式。它是对象的原基于ECMAScript的一个子集,采用完全独立于编程语言的转对n转文本格式来存储和表示数据。简洁和清晰的象源析层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,码解同时也易于机器解析和生成,并有效地提升网络传输效率。接下来看下JSON格式中定义的数据类型:
Object: Object在JSON中相当于C#的字典,是一个表,结构为{ key1: v1, key2: v2};
Array: Array在JSON中相当于C#的List,是一个数组,结构为[v0, v1, v2, …];
Boolean: Boolean在JSON中相当于C#的boolean;
Double: Double在json中相当于C#的double;
Float: Float在json中相当于C# float;
Int: Int在json中相当于C# int;
Long: Long在json中相当于C# long;
String: String在json中相当于C# string;
2: Unity中如何使用LitJson
Unity项目中使用LitJson,操作起来也十分简单。接下来我们详细的操作一下,具体步骤如下:
(1): 创建一个标准的Unity项目,下载LitJson的代码库,我一般会新建一个3rd文件夹,把LitJson的代码库放入到项目中,如图所示:
(2): 编写一个测试节点,挂一个测试代码,用来测试与讲解LitJson库的使用,同时编写一个JsonText.txt的文本资源,作为测试的Json文本,如图:
(3): Json编码
定义一个简单的数据对象GameItem, 如下
运行结果为:{ "a":,"b":false,"c":,"str":"hello"}, 如下图:
(4) Json解码
从JsonText.txt文件里面加载TextAsset资源,或去资源中的文本对象,得到JsonStr, 调用JsonWrapper对象的ToObject方法得到JsonData的数据对象。
JsonDatajsonObject=JsonMapper.ToObject(jsonTxt.text);
解析出来jsonObject后,可以根据json中的对象类型来直接访问即可。
JsonData rst = jsonObject["rst"]; // 子Object对象
JsonData partnerList = rst["partnerCodeList"]; // 数组对象
JsonData partner0 = partnerList[0]; // 用数组方式访问
JsonData可以强转成任意的lvm 源码基本数据类型,string, float, double, boolean, int等。
3:LitJson核心源码分析
LitJson使用起来如此简单,那么它是具体怎么实现的呢?接下来我们来分析LitJson源码来学习它代码开发的一些技巧。首先要看下JsonData数据结构,在LitJson内部,每个数据对象都是一个JsonData对象。如图
JsonData里面包含了一个JsonType type的数据成员,用来表示这个JsonData的数据对象是一个什么样的数据类型。JsonType是一个枚举,正好是所有可能的Json的数据类型,如下:
如果这个数据类型是一个Boolean,数据值就存放在inst_boolean变量里面,如果数据类型是一个string, 数据值就存放在inst_string变量里面。
在JSON中,Object与Array是容器,所以在JsonData里面分别用Dictionary与List来作为Object与Array的容器,容器中的每个元素又是一个JsonData,所以就实现了容器中可以有容器对象+数据对象。
JsonData中重载了[]操作符,方便容器对象来取数据,如图所示:
Object 容器对象[key]操作重载
数组容器对象的[index]操作重载
JsonData中重载了类型强转操作符,让我们能直接通过强转Json来获取基本的数据:
Int, Float, Double, Boolean, String。如图:
通过强转基本数据到JsonData,来获取JsonData, 如图:
这样非常方便的让我们生成了JsonData,非常方便的能通过JsonData获取数据。
JsonWrapper来解析Json字符串的时候,就是读取文本内容,来根据对应的Token符号来生成对应的Json对象,具体可以阅读源码:
今天的JSON与LitJson的分析就到这里了。
探索Android开源框架 - 8. Gson使用及源码解析
深入解析Android开源框架中的Gson使用及其源码解析,Gson作为Java语言的高效JSON转换库,以其简洁的API和高性能的特点,成为Android开发中进行数据序列化和反序列化的首选工具。本文将详细介绍Gson的使用方法,包括基本的解析与生成、属性重命名、POJO与JSON的字段映射规则、泛型的封装、序列化与反序列化过程,以及如何进行字段过滤与自定义序列化器和反序列化器的实现。
1. **基本的解析与生成
**使用Gson进行JSON字符串解析时,可以通过Gson对象的dskin 源码fromJson方法将JSON字符串转换为Java对象,反之,使用toJson方法将Java对象转换为JSON字符串。
2. **属性重命名
**通过使用@SerializedName注解,可以方便地在POJO类中重命名JSON字段,以匹配服务端返回的数据结构,从而避免硬编码的字符串匹配。
3. **POJO与JSON的字段映射规则
**Gson通过构建一个映射规则来匹配JSON字段到POJO类的属性,确保数据的正确解析与生成。这主要通过类型适配器(TypeAdapter)来实现,使得Gson能够理解如何处理复杂数据类型,如日期、集合等。
4. **泛型的封装
**在使用Gson进行序列化和反序列化时,可以通过泛型来保证类型安全,确保不会出现类型转换错误。GsonBuilder提供了一系列方法来实现泛型的封装,使得API调用更为清晰和明确。
5. **Gson的序列化、反序列化
**通过Gson的API,可以轻松实现Java对象到JSON字符串的序列化,以及从JSON字符串反序列化到Java对象的过程。这使得数据在不同系统间传输变得简单高效。
6. **字段过滤
**提供了多种方法进行字段过滤,如使用@Expose注解、基于版本的过滤、访问修饰符、以及基于策略的自定义过滤规则,以满足不同的数据处理需求。
7. **TypeAdapter、JsonSerializer与JsonDeserializer
**实战中,可能需要处理一些特殊的数据类型或复杂逻辑,这时可以通过实现JsonSerializer或JsonDeserializer来自定义序列化和反序列化过程。TypeAdapter则可以用于处理复杂类型的序列化。
8. **实战TypeAdapterFactory
**在某些场景下,drawtext源码可以通过实现TypeAdapterFactory来创建自定义的TypeAdapter,从而实现更为灵活的数据处理逻辑。
9. **@JsonAdapter注解
**用于指定自定义的序列化器或反序列化器,简化了实现自定义序列化逻辑的步骤,使得代码更为简洁和易读。
. **源码解析
**通过深入源码分析,可以更好地理解Gson内部的实现机制,如fromJson方法如何获取适配器、getAdapter方法如何选择适配器、Gson的构造方法如何初始化适配器列表,以及如何通过反射机制创建绑定字段等关键逻辑。这不仅有助于解决实际开发中的问题,还能加深对Gson工作的理解,为后续的优化和定制提供基础。
Unity JSON编码解码 之 LitJson 深度剖析
JSON,即JavaScript Object Notation,是一种轻量级的数据交换格式,它基于ECMAScript标准,以文本形式表示数据,易于人读和机器解析,提高网络传输效率。基本数据类型包括Boolean、Double、Float、Int、Long和String,而Object和Array则作为容器,可嵌套其他类型的数据。
编码(序列化)过程是将编程语言中的数据对象转换为JSON文本,解码(反序列化)则是解析JSON文本,识别数据类型,如识别花括号{ }表示对象,方括号[]表示数组。Unity C#中,skyline 源码 LitJson库常用于处理JSON的编码和解码。
在Unity项目中使用LitJson,步骤简单:首先,将库下载并添加到项目中;然后,定义一个测试数据对象,如GameItem,进行编码和解码操作。编码时,使用JsonMapper的ToJson方法将对象转换为Json String;解码时,通过JsonMapper的ToObject方法将JsonText.txt中的文本解析为JsonData对象,进而访问其中的数据。
LitJson的核心源码分析,JsonData是其核心数据结构,它以JsonType枚举表示数据类型,存储相应类型的数据。Object和Array分别用Dictionary和List作为容器,通过重载[]操作符和类型强转操作符,实现了灵活的数据访问和转换。JsonWrapper则负责解析JSON字符串,生成对应的Json对象。
从一个 JSON.parse 错误深入研究 JavaScript 的转义字符
JSON.parse 是将 JSON 字符串转化为 JavaScript 对象的函数。
尝试解析包含反斜杠转义的字符串,发现输出结果与预期不同,且出现异常。
通过测试不同数量的反斜杠,发现 3 个或以下会抛出异常,而 4 个则正常解析。
将 JSON.parse 部分去除,仅输出原始字符串,问题指向转义字符处理规则。
JSON 字符串解析规则指出,遇到反斜杠时,需按规则解析,而实际解析中出现了问题。
不仅 JSON,其他语言在处理非法转义字符时也会抛出错误。
JavaScript 特殊处理非法转义字符,通过直接忽略解决,这一规则未在 es 规范中详细描述。
深入解析 JavaScript 解析器代码,发现其主要通过读取源码并进行词法分析。
解析过程中,遇到双引号或单引号时调用特定函数,而单引号需要转义,双引号则不需要。
在解析字符串时,对于非法转义字符,最终判断为非法(Token::ILLEGAL)。
具体到转义字符处理,仅在遇到特定非法组合时返回 false,否则解释为非转义版本。
综上所述,JavaScript 对转义字符的处理与 JSON 不同,导致解析中出现的 bug。JSON 遇到非法字符直接异常,而 JavaScript 则解析为非转义版本,这一差异揭示了问题所在。
python爬虫的一个问题,json.loads()不式转化字符串为dict类型吗?
你看的那个网上解释,不准确的。
json.loads是将json对象转成原生对象。。。也就是说,原来是啥对象,就能给你转出来。只是数据类型,json只支持str类型。如果你原来的对象是dict类型,当然可以用data.keys()方法。但既然错误提示你的事原来的对象是str。。。
cJSON源码解析 - 数据存储方式
cJSON通过双向链表结构来组织数据,类似于一棵无序且可嵌套的键值对树。每个节点都有next和prev指针,分别指向其兄弟节点,这样在树中可以通过这些指针轻松查找。只有当节点是对象或数组时,才会存在child指针,用于访问下一层的子节点。
数据的存储方式具体如下:每个节点包含string类型用于存储键名,valuestring、valueint、valuedouble分别对应不同类型的内容。cJSON定义了多种结构类型,每一种类型(如cJSON_Creatxxx)都对应一个cJSON结构实例。
为了更直观地理解数据的组织,考虑以下示例:每个cJSON实例在内存中以这样的形式相连(简化版的图示省略):
JSONObject转换为对象时,转换后的对象为空
在进行 JSONObject 转换为对象操作时,若发现转换后的对象为空,意味着可能存在代码逻辑问题或是相关转换函数实现的缺失。首先检查代码实现,确认逻辑正确性。
执行结果显示对象为空的结果。通过调试,发现问题根源在于底层使用了 PropertyDescriptor 反射来获取属性,通过 PropertyDescriptor.getWriteMethod() 方法来获取属性的 setter 方法。问题在于此方法返回值必须为 void,否则将会返回 null,造成后续赋值操作无法执行。
通过分析 getWriteMethod() 源代码,得出 setter 方法的返回值类型必须满足特定要求。通常,setter 方法的目标是修改对象属性,不应带有返回值。然而,在使用了 @Accessors(chain = true) 标注的 lombok 注解后,生成的 setter 方法实现了链式调用功能,其返回值为对象本身而非 void,这正是导致 PropertyDescriptor 无法识别的关键原因。
要解决此问题,建议在使用 @Builder 时确保同时引入 @NoArgsConstructor 和 @AllArgsConstructor。当遇到 @Builder 注解时,确保代码中包含无参构造方法(@NoArgsConstructor)和全参构造方法(@AllArgsConstructor),以避免因构造方法缺失或错误而导致的异常。这样的配置可确保对象能够根据 Builder 的需求正确地初始化属性,从而解决转换过程中对象为空的问题。
C++实现JSON转换(重点看nlohmann/json的使用)
nlohmann/json 是一个功能强大的 JSON 数据处理库,它通过简洁直观的接口,为 C++ 应用程序提供了灵活性和高效性,使得 JSON 数据的使用变得简单可靠。
然而,在使用 nlohmann/json 转换 JSON 时,需要事先指定字段名,无法像 Java 那样通过反射机制自动获取类的属性。C++ 目前尚未实现类似的反射机制,动态正反向解析 JSON。除非通过宏的方式自行实现,但这相对复杂
1. 接下来看看 RapidJSON
这是一个快速的 C++ JSON 解析/生成器,支持将 C++ 对象序列化为 JSON 并进行反向操作。
官方网站:RapidJSON
实例代码如下:
A:RapidJSON 的安装和配置
使用第三方库必然需要安装,以下为教程:
2. nlohmann/json
GitHub页面:nlohmann/json
示例代码
A:获取源码
访问 nlohmann/json GitHub 页面,将其下载到本地
B:构建和安装
由于 nlohmann/json 是一个纯头文件库,不需要编译和安装过程。只需将其头文件复制到你的项目中
如果你的项目使用 CMake 进行构建,可以考虑将 JSON for Modern C++ 添加为一个子模块,并将其链接到你的项目中。这样可以更方便地管理依赖关系。
B-1:我这里选择的是手动下载文件库-从git下载代码
下载后解压,然后找到这个简化版的头文件目录
B-2:将这两个文件拷贝到项目中
B-3:在项目中引入头文件tests 单元测试类引入
引入头文件,需要先修改 CMakeList.txt 文件
其中解释如下:
其中 ark_threadpool 是我项目的名字
C:上面的例子运行结果
安装完成后
D:如果是 src 目录,那不用给每个文件生成可执行文件,所以配置如下
3. 扩展知识:如何添加 C++ 子模块 这是 git 的功能
Git 的子模块功能允许你在一个 Git 仓库中包含另一个 Git 仓库。这种功能使得一个项目可以依赖于另一个项目或库,这些依赖关系可以被管理和更新。
添加子模块的步骤
例如,添加 JSON for Modern C++ 作为子模块的命令是:
这条命令将 JSON for Modern C++ 作为名为 external/json 的子模块添加到你的项目中。一旦添加,你可以通过以下方式使用它:
这么做的好处
4. 扩展只是:.hpp 头文件的作用
.hpp 是 C++ 中头文件的命名约定,通常用于包含 C++ 类声明、函数声明、常量定义等。它与传统的 .h 文件(头文件)类似,但更常见于现代 C++ 项目中,用于区分 C++ 特定的头文件。
注意,如果你的项目想将其作为 .hpp 文件提供给其他项目使用,通常需要通过脚本实现。没有现成的工具可以合成。另外,.hpp 方式的引入会导致项目编译速度非常慢
可以参考以下文章:
手把手教你实现json嵌套对象的范式化和反范式化
手把手教你实现JSON嵌套对象的范式化和反范式化 在处理复杂JSON数据时,将嵌套对象转换为范式化数据有助于简化前端逻辑。例如,后端返回的复杂JSON结构可能需要前端提取并展示,但嵌套过深会增加前端代码的复杂度。尤其在使用状态管理工具(如Flux或Redux)时,将状态对象(state)范式化,可降低操作复杂性,便于清晰地跟踪视图更新过程。 范式化的过程是将数据结构简化,例如,将一个包含嵌套的person对象转换为:主对象person的其他属性作为核心,如姓名、年龄,
而爱好(hobby)用外键(如id)引用另一个单独的对象,如hobby表。
范式化的优点在于,当添加新数据时,只需改动一处(外键对象),即使数据涉及多个实例,也能避免冗余修改。然而,这可能牺牲查询性能,因为需要通过外键查找具体值,而不是直接展示嵌套对象。 实现范式化和反范式化的关键在于编写函数,如schema.Entity,它接受数据和定义的实体关系。范式化函数(normalize)会处理原始数据,递归地处理嵌套结构,确保数据符合范式化要求。反范式化函数(denormalize)则是将范式化数据恢复到原始嵌套结构。 最后,为了验证代码的正确性,可以编写简单的单元测试,确保范式化和反范式化的转换是准确无误的。具体实现细节可以参考源代码,但这里不赘述。2024-11-14 10:24
2024-11-14 09:02
2024-11-14 08:59
2024-11-14 08:40
2024-11-14 08:32