Protobuf(Protocol Buffers)和JSON(JavaScript Object Notation)是两种不同的数据序列化格式,二者区别如下:
-
数据结构描述:
- Protobuf: 使用专门的IDL(Interface Definition Language)语言来描述数据结构,称为
.proto文件。这些文件定义了消息的字段、类型和消息格式,然后通过编译器生成对应的数据访问类。 - JSON: 使用自描述性强的文本格式来表示数据,字段和值之间通过键值对的方式组织。JSON的结构直接写在数据中,不需要额外的定义文件。
- Protobuf: 使用专门的IDL(Interface Definition Language)语言来描述数据结构,称为
-
数据体积:
- Protobuf: 序列化后的数据通常比JSON更为紧凑,因为它使用了二进制格式,省略了大量的标记和冗余信息。
- JSON: 虽然易于阅读和理解,但是其文本格式相对来说较为冗长,会占用更多的网络传输带宽和存储空间。
-
解析性能:
- Protobuf: 解析速度比JSON更快,因为二进制格式的数据可以直接转换成内存中的数据结构,而不需要解析文本。
- JSON: 解析JSON需要进行文本解析和字符处理,相对来说速度较Protobuf慢一些。
-
跨语言支持:
- Protobuf: 设计上支持多种编程语言的生成器,可以生成对应的数据访问类,使得在不同语言之间进行数据交换更加方便。
- JSON: 虽然也有广泛的语言支持,但是不像Protobuf那样有一套严格的定义和生成机制。
-
可读性:
- Protobuf: 由于是二进制格式,不像JSON那样易于人类阅读和理解。通常被设计用于机器间的通信和数据存储。
- JSON: 易于阅读和编写,适合人类阅读和编辑,也可以用于配置文件和简单的数据交换。
Protobuf适合于对数据传输效率和解析性能有较高要求的场景,而JSON则更适合于简单的数据交换和易读性要求较高的场景
使用 json-c API 来实现 JSON 数据的封装(序列化)和解封装(反序列化)
JSON封装(序列化)
#include <stdio.h>
#include <json-c/json.h>
struct Person {
const char* name;
int age;
const char* email;
};
int main() {
// 创建一个Person对象
struct Person person = {
.name = "John Doe",
.age = 30,
.email = "john.doe@example.com"
};
// 创建JSON对象
struct json_object *j_person = json_object_new_object();
json_object_object_add(j_person, "name", json_object_new_string(person.name));
json_object_object_add(j_person, "age", json_object_new_int(person.age));
json_object_object_add(j_person, "email", json_object_new_string(person.email));
// 将JSON对象转换为字符串
const char *jsonString = json_object_to_json_string(j_person);
// 打印序列化后的JSON字符串
printf("Serialized JSON:\n%s\n", jsonString);
// 释放JSON对象
json_object_put(j_person);
return 0;
}
JSON解封装(反序列化)
#include <stdio.h>
#include <json-c/json.h>
struct Person {
const char* name;
int age;
const char* email;
};
int main() {
// 示例的JSON字符串
const char *jsonString = "{\"name\":\"Jane Smith\",\"age\":25,\"email\":\"jane.smith@example.com\"}";
// 解析JSON字符串为JSON对象
struct json_object *j_person = json_tokener_parse(jsonString);
// 从JSON对象中提取数据并填充到Person对象中
struct Person person;
json_object_object_get_ex(j_person, "name", &j_person);
person.name = json_object_get_string(j_person);
json_object_object_get_ex(j_person, "age", &j_person);
person.age = json_object_get_int(j_person);
json_object_object_get_ex(j_person, "email", &j_person);
person.email = json_object_get_string(j_person);
// 打印解析得到的Person对象的数据
printf("Name: %s\n", person.name);
printf("Age: %d\n", person.age);
printf("Email: %s\n", person.email);
// 释放JSON对象
json_object_put(j_person);
return 0;
}
- 在使用
json-c时,需要包含头文件<json-c/json.h>。 - JSON对象的创建、释放和数据获取使用了
json_object_new_*()和json_object_get_*()等函数。 json_tokener_parse()函数用于将JSON字符串解析为json_object对象。- 使用
json_object_put()函数释放json_object对象,避免内存泄漏
1177

被折叠的 条评论
为什么被折叠?



