C++ JSON库 nlohmann::basic_json::binary_t的用法

简介: C++ JSON库 nlohmann::basic_json::binary_t的用法

简介

nlohmann::basic_json::binary_t 是一个类型别名,用于表示二进制数据。它是 nlohmann::json 库的一部分,这是一个流行的 C++ JSON 处理库。

nlohmann::json 库中,binary_t 是一个类型别名,用于表示二进制数据。具体来说,它是一个 std::vector<uint8_t>,可以用来存储任意的二进制数据。

以下是如何使用 binary_t 的一个简单示例:

#include <nlohmann/json.hpp>
int main() {
    // 创建一个包含二进制数据的 vector
    std::vector<uint8_t> binary_data = {0x01, 0x02, 0x03, 0x04};
    // 创建一个 binary_t 对象
    nlohmann::json::binary_t my_binary(binary_data);
    // 创建一个 JSON 对象并将 binary_t 对象存储在其中
    nlohmann::json j;
    j["my_binary_data"] = my_binary;
    // 输出 JSON 对象
    std::cout << j << std::endl;
    return 0;
}

在这个示例中,我们首先创建了一个包含一些二进制数据的 std::vector<uint8_t>。然后,我们使用这个 vector 创建了一个 binary_t 对象。最后,我们创建了一个 JSON 对象,并将 binary_t 对象存储在其中。

注意,nlohmann::json 库默认情况下不支持二进制数据。要启用对二进制数据的支持,你需要在包含 nlohmann/json.hpp 之前定义 JSON_USE_IMPLICIT_CONVERSIONS 宏,并将其值设置为 0。例如:

#define JSON_USE_IMPLICIT_CONVERSIONS 0
#include <nlohmann/json.hpp>

这将禁用库中的所有隐式转换,包括将 std::vector<uint8_t> 自动转换为 binary_t。然后,你可以显式地创建 binary_t 对象,并将它们存储在 JSON 对象中。

nlohmann::basic_json::binary_t 官网介绍

using binary_t = byte_container_with_subtype<BinaryType>;

这种类型是为了承载出现在各种序列化格式中的二进制数据而设计的,如 CBOR 的 Major Type 2,MessagePack 的 bin,和 BSON 的通用二进制子类型。这种类型不是标准 JSON 的一部分,仅仅是为了与这些二进制类型的兼容性而存在。因此,它只是定义为零个或多个字节值的有序序列。

此外,作为实现细节,二进制数据的子类型作为 std::uint64_t 被携带,这与使用二进制子类型的二进制数据格式兼容(尽管具体的编号与彼此不兼容,用户需要在它们之间进行转换)。子类型通过帮助类型 byte_container_with_subtype 添加到 BinaryType

CBOR’s RFC 7049 描述这种类型为:

Major type 2: a byte string. The string’s length in bytes is represented following the rules for positive integers (major type 0).

MessagePack’s documentation on the bin type family 描述这种类型为:

Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array.

BSON’s specifications 描述了几种二进制类型;然而,这种类型旨在表示通用二进制类型,其描述为:

Generic binary subtype - This is the most commonly used binary subtype and should be the ‘default’ for drivers and tools.

这些都没有对内部表示施加任何限制,除了存储的基本单位是可以分解为字节的某种类型的数组。

这种二进制格式的默认表示是 std::vector<std::uint8_t>,这是在现代 C++ 中表示字节数组的一种非常常见的方式。

模板参数

  • BinaryType:用于存储数组的容器类型

注意事项

默认类型

BinaryType 的默认值是 std::vector<std::uint8_t>

存储

二进制数组在 basic_json 类型中存储为指针。也就是说,对于任何对数组值的访问,必须解引用类型为 binary_t* 的指针。

关于子类型的注意事项

  • CBOR
  • 二进制值表示为字节字符串。子类型被写为标签。
  • MessagePack
  • 如果给定了子类型,并且二进制数组包含恰好 1、2、4、8 或 16 个元素,那么使用 fixext family(fixext1、fixext2、fixext4、fixext8)。对于其他大小,使用 ext family(ext8、ext16、ext32)。
  • BSON
  • 如果给定了子类型,那么它被写为二进制值的子类型。

示例

#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
    // create binary values
    json::binary_t foo = {1, 2, 3, 4};
    json::binary_t bar = {5, 6, 7, 8};
    // create a JSON array with binary values
    json j = {foo, bar};
    // serialize the JSON array
    std::cout << j << '\n';
    // deserialize the JSON array
    json j2 = json::parse(j.dump());
    // access the binary values
    for (const auto& bin : j2)
    {
        for (uint8_t byte : json::binary_t(bin))
        {
            std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << ' ';
        }
        std::cout << '\n';
    }
}

另请参阅

版本历史

  • 在版本 3.8.0 中添加。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。

目录
相关文章
|
20天前
|
存储 C++ 容器
C++STL(标准模板库)处理学习应用案例
【4月更文挑战第8天】使用C++ STL,通过`std:vector`存储整数数组 `{5, 3, 1, 4, 2}`,然后利用`std::sort`进行排序,输出排序后序列:`std:vector<int> numbers; numbers = {5, 3, 1, 4, 2}; std:sort(numbers.begin(), numbers.end()); for (int number : numbers) { std::cout << number << " "; }`
19 2
|
1月前
|
缓存 算法 C语言
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
48 0
|
18天前
|
C++
glog --- C++日志库
glog --- C++日志库
|
26天前
|
人工智能 安全 机器人
【C++】const_cast基本用法(详细讲解)
【C++】const_cast基本用法(详细讲解)
|
26天前
|
人工智能 机器人 中间件
【C++】C++回调函数基本用法(详细讲解)
【C++】C++回调函数基本用法(详细讲解)
|
26天前
|
XML JSON JavaScript
推荐一个比较好用的c++版本http协议库-cpp-httplib
推荐一个比较好用的c++版本http协议库-cpp-httplib
38 1
|
1月前
|
算法 安全 编译器
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
25 1
|
1月前
|
安全 网络性能优化 Android开发
深入解析:选择最佳C++ MQTT库的综合指南
深入解析:选择最佳C++ MQTT库的综合指南
90 0
|
1月前
|
XML 运维 监控
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
68 0
|
1月前
|
存储 JSON Apache
揭秘 Variant 数据类型:灵活应对半结构化数据,JSON查询提速超 8 倍,存储空间节省 65%
在最新发布的阿里云数据库 SelectDB 的内核 Apache Doris 2.1 新版本中,我们引入了全新的数据类型 Variant,对半结构化数据分析能力进行了全面增强。无需提前在表结构中定义具体的列,彻底改变了 Doris 过去基于 String、JSONB 等行存类型的存储和查询方式。
揭秘 Variant 数据类型:灵活应对半结构化数据,JSON查询提速超 8 倍,存储空间节省 65%