提问人:Стас 提问时间:6/13/2023 更新时间:6/13/2023 访问量:83
将 boost::beast::multibuffer 转换为 std::istream
Convert boost::beast::multibuffer to std::istream
问:
我正在从方法中获取对象。然后,我想像这样从中解析json内容:boost::beast::multibuffer
http::response<http::dynamic_body>::body()
boost::property_tree::read_json(requestBodyStream, propertyTree);
我应该使用 and 获取,还是可以在不花费太多内存来复制缓冲区内容的情况下进行?boost::beast::buffers_to_string
std::stringstream
requestBodyStream
答:
1赞
sehe
6/13/2023
#1
一般来说,不要对具体的实现进行编程,而是对概念进行编程。在这里,文件:dynamic_body
此正文使用 a 作为基于内存的容器来保存消息有效负载。使用此正文类型的消息可以序列化和分析。
DynamicBuffer
你不需要这个概念,因为无论如何你都会完全在内存中使用这个概念,但如果你这样做了,你会像这样去做:
net::streambuf sb;
sb.commit(net::buffer_copy(sb.prepare(body.size()), body.cdata()));
std::istream is(&sb);
ptree doc;
read_json(is, doc);
#include <boost/asio.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/beast/http.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
namespace net = boost::beast::net;
namespace http = boost::beast::http;
using boost::property_tree::ptree;
int main() {
net::posix::stream_descriptor input(net::system_executor{}, 0); // stdin
http::response<http::dynamic_body> res;
{
net::streambuf readbuf;
http::read(input, readbuf, res);
}
auto& body = res.body();
net::streambuf sb;
sb.commit(net::buffer_copy(sb.prepare(body.size()), body.cdata()));
std::istream is(&sb);
ptree doc;
read_json(is, doc);
write_json(std::cout << "Parsed body: ", doc);
}
它读取来自 stdin 的示例响应,让我们使用
HTTP/1.1 200 OK
Content-Length: 50
{"this":{"is":[1,2,3], "a":"sample"}, "object":42}
这样:
g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp && ./a.out <<< $'HTTP/1.1 200 OK\r\nContent-Length: 50\r\n\r\n{\"this\":{\"is\":[1,2,3], \"a\":\"sample\"}, \"object\":42}'
指纹
Parsed body: {
"this": {
"is": [
"1",
"2",
"3"
],
"a": "sample"
},
"object": "42"
}
然而
现在我们已经回答了这个问题,让我们添加上下文:
不要使用 Boost 属性树(除非您需要属性树。提示:你没有)。查看输出:属性树不是 JSON 库
除非您需要,否则不要使用动态身体。在这种情况下,您将在内存中读取整个消息,将其复制到内存中(以转换为流式处理),使用区域设置感知的 istream(慢速)从中读取消息,结果在内存中作为另一个副本存在。
相反,请使用最简单的模型并使用 JSON 库,例如,您知道,Boost.JSON:
#include <boost/asio.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/beast/http.hpp>
#include <boost/json/src.hpp> // for header-only
#include <iostream>
namespace net = boost::beast::net;
namespace http = boost::beast::http;
namespace json = boost::json;
int main() {
net::posix::stream_descriptor input(net::system_executor{}, 0); // stdin
http::response<http::string_body> res;
{
net::streambuf readbuf;
http::read(input, readbuf, res);
}
auto doc = json::parse(res.body());
std::cout << "Parsed body: " << doc << "\n";
}
它代码更少,效率更高,最重要的是,正确处理 JSON!
评论
0赞
Стас
6/13/2023
谢谢!不知道)
评论