文章目录
- jsoncpp库
- json 认识
- jsoncpp 认识
- jsoncpp 实现序列化
- jsoncpp 实现反序列化
- bundle库
- bundle库实现文件压缩
- bundle库实现文件解压缩
- httplib 库
- httplib 库搭建简单服务器
- httplib库搭建简单客户端
jsoncpp库
json 认识
json 是一种数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。
例如:
json 数据类型:对象,数组,字符串,数字
对象:使用花括号 {} 括起来的表示一个对象。
数组:使用中括号 [] 括起来的表示一个数组。
字符串:使用常规双引号 “” 括起来的表示一个字符串
数字:包括整形和浮点型,直接使用
jsoncpp 认识
//Json数据对象类
class Json::Value{
Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取数据都可以通过
Value& operator[](const std::string& key);//简单的方式完成 val["姓名"] = "小明";
Value& operator[](const char* key);
Value removeMember(const char* key);//移除元素
const Value& operator[](ArrayIndex index) const; //val["成绩"][0]
Value& append(const Value& value);//添加数组元素val["成绩"].append(88);
ArrayIndex size() const;//获取数组元素个数 val["成绩"].size();
std::string asString() const;//转string string name = val["name"].asString();
const char* asCString() const;//转char* char *name = val["name"].asCString();
Int asInt() const;//转int int age = val["age"].asInt();
float asFloat() const;//转float
bool asBool() const;//转 bool
};
//json序列化类,低版本用这个更简单
class JSON_API Writer {
virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {
virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer {
virtual std::string write(const Value& root);
}
//json序列化类,高版本推荐,如果用低版本的接口可能会有警告
class JSON_API StreamWriter {
virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
virtual StreamWriter* newStreamWriter() const;
}
//json反序列化类,低版本用起来更简单
class JSON_API Reader {
bool parse(const std::string& document, Value& root, bool collectComments = true);
}
//json反序列化类,高版本更推荐
class JSON_API CharReader {
virtual bool parse(char const* beginDoc, char const* endDoc,
Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
virtual CharReader* newCharReader() const;
jsoncpp 实现序列化
运行结果:
jsoncpp 实现反序列化
运行结果:
我们都知道在初学c++和c的时候总是要在输出时输出类似于"\" ,‘%’ ,’ " ’等等一系列符号。我们常用的方法是在输出里面用上双斜杠,或者说是双%%,那么我们到底还有没有其他的方法呢?
所以今天我们要介绍的就是我们的主角R了;
在c++中我们可以使用以R"+(为开头,并且以)+"为结尾来输出我们想要的任何语句,包括%和\。
bundle库
BundleBundle 是一个嵌入式压缩库,支持23种压缩算法和2种存档格式。使用的时候只需要加入两个文件bundle.h 和 bundle.cpp 即可。
namespace bundle
{
// low level API (raw pointers)
bool is_packed( *ptr, len );
bool is_unpacked( *ptr, len );
unsigned type_of( *ptr, len );
size_t len( *ptr, len );
size_t zlen( *ptr, len );
const void *zptr( *ptr, len );
bool pack( unsigned Q, *in, len, *out, &zlen );
bool unpack( unsigned Q, *in, len, *out, &zlen );
// medium level API, templates (in-place)
bool is_packed( T );
bool is_unpacked( T );
unsigned type_of( T );
size_t len( T );
size_t zlen( T );
const void *zptr( T );
bool unpack( T &, T );
bool pack( unsigned Q, T &, T );
// high level API, templates (copy)
T pack( unsigned Q, T );
T unpack( T );
}
bundle库实现文件压缩
#include <iostream>
#include <string>
#include <fstream>
#include "bundle.h"
int main(int argc, char* argv[])
{
if(argc != 3)
{
std::cout << argv[0]<< " sourceFileName compressedFileName" << std::endl;
exit(0);
}
std::string ifilename = argv[1];
std::string ofilename = argv[2];
std::ifstream ifs;
ifs.open(ifilename, std::ios::binary);
ifs.seekg(0, std::ios::end);//跳转到文件末尾
size_t fsize = ifs.tellg();//从头到末尾的字节大小
ifs.seekg(0, std::ios::beg);//回到文件头部
std::string buffer;
buffer.resize(fsize);
ifs.read(&buffer[0], buffer.size());
std::string paked = bundle::pack(bundle::LZIP, buffer);
std::ofstream ofs;
ofs.open(ofilename, std::ios::binary);
ofs.write(&paked[0], paked.size());
ifs.close();
ofs.close();
return 0;
}
生成可执行程序:
运行可执行程序
./bundle + 要压缩的文件名 + 压缩后的文件名.lz
bundle库实现文件解压缩
#include <iostream>
#include <string>
#include <fstream>
#include "bundle.h"
int main(int argc, char* argv[])
{
if(argc != 3)
{
std::cout << argv[0]<< " compressedFileName sourceFileName" << std::endl;
exit(0);
}
std::string ifilename = argv[1];
std::string ofilename = argv[2];
std::ifstream ifs;
ifs.open(ifilename, std::ios::binary);
ifs.seekg(0, std::ios::end);
size_t fszie = ifs.tellg();
ifs.seekg(0, std::ios::beg);
std::string buffer;
buffer.resize(fszie);
ifs.read(&buffer[0], buffer.size());
std::string unpaked = bundle::unpack(buffer);
std::ofstream ofs;
ofs.open(ofilename, std::ios::binary);
ofs.write(&unpaked[0], unpaked.size());
ifs.close();
ofs.close();
return 0;
}
生成可执行程序:
运行结果:
./bundle + 要解压缩的文件 + 解压后的文件名
httplib 库
httplib 库,一个 C++11 单文件头的跨平台HTTP/HTTPS库。安装起来非常容易。只需包含 httplib.h 在你的代码中即可。
httplib 库实际上是用于搭建一个简单的 http 服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率。
namespace httplib{
struct MultipartFormData {
std::string name;
std::string content;
std::string filename;
std::string content_type;
};
using MultipartFormDataItems = std::vector<MultipartFormData>;
//请求类
struct Request {
std::string method;
std::string path;
Headers headers;
std::string body;
// for server
std::string version;
Params params;
MultipartFormDataMap files;
Ranges ranges;
bool has_header(const char *key) const;
std::string get_header_value(const char *key, size_t id = 0) const;
void set_header(const char *key, const char *val);
bool has_file(const char *key) const;
MultipartFormData get_file_value(const char *key) const;
};
//响应类
struct Response {
std::string version;
int status = -1;
std::string reason;
Headers headers;
std::string body;
std::string location; // Redirect location
void set_header(const char *key, const char *val);
void set_content(const std::string &s, const char *content_type);
};
//服务端类,可用于搭建服务端
class Server {
using Handler = std::function<void(const Request &, Response &)>;
using Handlers = std::vector<std::pair<std::regex, Handler>>;
std::function<TaskQueue *(void)> new_task_queue;
Server &Get(const std::string &pattern, Handler handler);
Server &Post(const std::string &pattern, Handler handler);
Server &Put(const std::string &pattern, Handler handler);
Server &Patch(const std::string &pattern, Handler handler);
Server &Delete(const std::string &pattern, Handler handler);
Server &Options(const std::string &pattern, Handler handler);
bool listen(const char *host, int port, int socket_flags = 0);
};
//客户端搭建类,可用于搭建客户端
class Client {
Client(const std::string &host, int port);
Result Get(const char *path, const Headers &headers);
Result Post(const char *path, const char *body, size_t content_length,
const char *content_type);
Result Post(const char *path, const MultipartFormDataItems &items);
}
}
httplib 库搭建简单服务器
#include <iostream>
#include "httplib.h"
//回调函数
void Hello(const httplib::Request &req, httplib::Response& rep)
{
rep.set_content("Hello World", "text/plain");
rep.status = 200;
}
//回调函数
void Numbers(const httplib::Request &req, httplib::Response& rep)
{
auto num = req.matches[1];
rep.set_content(num, "text/plain");
rep.status = 200;
}
//回调函数
void Multipart(const httplib::Request &req, httplib::Response& rep)
{
auto ret = req.has_file("file");
if(ret == false)
{
std::cout << "not file upload" << std::endl;
rep.status = 404;
return;
}
const auto& file = req.get_file_value("file");
rep.body.clear();
rep.body = file.filename;
rep.body += "\n";
rep.body += file.content;
rep.set_header("Content-Type", "text/plain");
rep.status = 200;
}
int main()
{
httplib::Server srv;
srv.Get("/hi", Hello);
srv.Get(R"(/numbers/(\d+))", Numbers);///numbers/(\d+)正则表达式
srv.Post("/multipart", Multipart);
srv.listen("0.0.0.0", 8080);
return 0;
}
运行服务端用浏览器访问
httplib库搭建简单客户端
#include <iostream>
#include "httplib.h"
#define SEVERIP "154.8.198.250"
#define SERVERPORT 8080
int main()
{
httplib::Client client(SEVERIP, SERVERPORT);
httplib::MultipartFormData item;
item.name = "file";
item.filename = "test.txt";
item.content = "Hello World";
item.content_type = "text/plain";
httplib::MultipartFormDataItems items;
items.push_back(item);
auto ret = client.Post("/multipart", items);
std::cout << ret->status << std::endl;
std::cout << ret->body << std::endl;
return 0;
}
客户端向服务器发送Post请求,服务器用srv.Post(“/multipart”, Multipart)中Multipart回调函数的处理请求,并构建响应
运行服务端和客户端: