You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Boost读取JSON中Buffer字段并存入std::string或asio buffer的方法咨询

C++ 读取JSON中Buffer数组字段解决方案

问题描述

我有如下JSON字符串:

{"message":
{"type":"Buffer",
"data":[0,0,0,193,0,41,10,190,1,34,128,0,0,1,38,0,0,1,232,41,40,202,35,104,81,66,0,162,194,173,0,254,67,116,38,60,235,70,250,195,139,141,184,47,167,240,210,207,118,184,140,225,82,52,30,35,111,80,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,33,2,155,92,51,188,68,15,123,37,47,245,59,120,114,102,60,233,15,212,39,112,165,190,210,14,188,25,156,234,124,154,181,101,118,71,48,69,2,33,0,242,181,45,125,208,73,206,26,86,183,220,28,159,36,149,124,208,72,187,118,116,44,224,252,192,173,242,248,112,181,63,49,2,32,84,83,33,39,113,80,183,50,225,212,133,84,226,26,173,185,65,216,237,234,90,20,215,136,184,246,229,230,13,227,69,42]},
"validator_key":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}

我需要读取message.data字段,该字段是Node.js进程通过gRPC返回的buffer。我尝试了如下实现代码:

std::stringstream ss;
boost::property_tree::ptree pt;
ss << gossip.message();

boost::property_tree::read_json(ss, pt);
auto message_received = pt.get<std::string>("message.data");

std::cout << "Message received pure: " << gossip.message() << std::endl;
std::cout << "Message received, json: " << message_received << std::endl;

其中gossip.message()是我通过gRPC接收到的原始JSON字符串,实际运行输出结果如下:

Message received pure: {"message":{"type":"Buffer","data":[0,0,0,193,0,41,10,190,1,34,128,0,0,1,38,0,0,1,232,41,40,202,35,104,81,66,0,162,194,173,0,254,67,116,38,60,235,70,250,195,139,141,184,47,167,240,210,207,118,184,140,225,82,52,30,35,111,80,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,33,2,155,92,51,188,68,15,123,37,47,245,59,120,114,102,60,233,15,212,39,112,165,190,210,14,188,25,156,234,124,154,181,101,118,71,48,69,2,33,0,242,181,45,125,208,73,206,26,86,183,220,28,159,36,149,124,208,72,187,118,116,44,224,252,192,173,242,248,112,181,63,49,2,32,84,83,33,39,113,80,183,50,225,212,133,84,226,26,173,185,65,216,237,234,90,20,215,136,184,246,229,230,13,227,69,42]},"validator_key":"n9MZdq6qPssK3jw63sjR8VRR4NjyCmaV11LnqTiCFQjRCDFreUVc\n"}
Message received, json: 

请问我应该如何正确读取该字段,将其存入std::string或者asio buffer中?


解决方案

问题原因

message.data在JSON中是数字数组类型,无法直接通过boost::property_tree::ptree::get<std::string>()方法读取,该方法只能读取字符串类型的节点值,所以返回为空。

正确实现步骤

  1. 先获取message.data对应的数组子节点
  2. 遍历数组所有元素,将每个数字转为字节存入容器
  3. 可直接将容器转为asio buffer使用

基于Boost.PropertyTree的实现代码

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <string>
#include <vector>
#include <asio.hpp> // 如果需要用asio buffer的话引入

// ... 原有代码
std::stringstream ss;
boost::property_tree::ptree pt;
ss << gossip.message();
boost::property_tree::read_json(ss, pt);

// 获取data数组节点
auto& data_node = pt.get_child("message.data");

// 存入std::string
std::string buffer_str;
buffer_str.reserve(data_node.size()); // 预分配空间提升性能

// 也可以选择存入std::vector<uint8_t>,更适合存储字节数据
// std::vector<uint8_t> buffer_vec;
// buffer_vec.reserve(data_node.size());

for (auto& item : data_node) {
    uint8_t byte_val = static_cast<uint8_t>(item.second.get_value<int>());
    buffer_str.push_back(static_cast<char>(byte_val));
    // buffer_vec.push_back(byte_val);
}

// 转为asio buffer
asio::const_buffer asio_buf(buffer_str.data(), buffer_str.size());
// 如果用vector的话:asio::const_buffer asio_buf(buffer_vec.data(), buffer_vec.size());

更简便的替代方案

如果项目允许更换JSON库,更推荐使用nlohmann/json库,无需手动遍历数组,一行代码即可完成读取:

#include <nlohmann/json.hpp>
using json = nlohmann::json;

// ...
auto j = json::parse(gossip.message());
auto buffer_vec = j["message"]["data"].get<std::vector<uint8_t>>();
// 转asio buffer同理
asio::const_buffer asio_buf(buffer_vec.data(), buffer_vec.size());

内容的提问来源于stack exchange,提问作者Flav Scheidt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:06:05