正如其他人所说:序列化可能是您问题的最佳解决方案。
由于您处于资源受限的环境中,因此我建议使用MsgPack 之类的东西。它只是头文件(给定一个 C++11 编译器),非常轻巧,格式简单,C++ 接口很好。它甚至允许您非常轻松地序列化用户定义的类型(即类/结构):
// adapted from https://github.com/msgpack/msgpack-c/blob/master/QUICKSTART-CPP.md
#include <msgpack.hpp>
#include <vector>
#include <string>
struct dataStruct {
int a;
double b, c, d, e, f, g, h, i, j, l, m, n, oo; // yes "oo", because "o" clashes with msgpack :/
MSGPACK_DEFINE(a, b, c, d, e, f, g, h, i, j, l, m, n, oo);
};
int main(void) {
std::vector<dataStruct> vec;
// add some elements into vec...
// you can serialize dataStruct directly
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, vec);
msgpack::unpacked msg;
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
msgpack::object obj = msg.get();
// you can convert object to dataStruct directly
std::vector<dataStruct> rvec;
obj.convert(&rvec);
}
作为替代方案,您可以查看 Google 的FlatBuffers。它似乎非常节省资源,但我还没有尝试过。
编辑:这是一个完整的示例,说明了整个序列化 - 文件 I/O - 反序列化周期:
// adapted from:
// https://github.com/msgpack/msgpack-c/blob/master/QUICKSTART-CPP.md
// https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
#include <msgpack.hpp>
#include <fstream>
#include <iostream>
using std::cout;
using std::endl;
struct dataStruct {
int a;
double b, c, d, e, f, g, h, i, j, l, m, n, oo; // yes "oo", because "o" clashes with msgpack :/
MSGPACK_DEFINE(a, b, c, d, e, f, g, h, i, j, l, m, n, oo);
};
std::ostream& operator<<(std::ostream& out, const dataStruct& ds)
{
out << "[a:" << ds.a << " b:" << ds.b << " ... oo:" << ds.oo << "]";
return out;
}
int main(void) {
// serialize
{
// prepare the (buffered) output file
std::ofstream ofs("log.bin");
// prepare a data structure
dataStruct ds;
// fill in sample data
ds.a = 1;
ds.b = 1.11;
ds.oo = 101;
msgpack::pack(ofs, ds);
cout << "serialized: " << ds << endl;
ds.a = 2;
ds.b = 2.22;
ds.oo = 202;
msgpack::pack(ofs, ds);
cout << "serialized: " << ds << endl;
// continuously receiving data
//while ( /* data is being received... */ ) {
//
// // initialize ds...
//
// // serialize ds
// // You can use any classes that have the following member function:
// // https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_packer#buffer
// msgpack::pack(ofs, ds);
//}
}
// deserialize
{
// The size may decided by receive performance, transmit layer's protocol and so on.
// prepare the input file
std::ifstream ifs("log.bin");
std::streambuf* pbuf = ifs.rdbuf();
const std::size_t try_read_size = 100; // arbitrary number...
msgpack::unpacker unp;
dataStruct ds;
// read data while there are still unprocessed bytes...
while (pbuf->in_avail() > 0) {
unp.reserve_buffer(try_read_size);
// unp has at least try_read_size buffer on this point.
// input is a kind of I/O library object.
// read message to msgpack::unpacker's internal buffer directly.
std::size_t actual_read_size = ifs.readsome(unp.buffer(), try_read_size);
// tell msgpack::unpacker actual consumed size.
unp.buffer_consumed(actual_read_size);
msgpack::unpacked result;
// Message pack data loop
while(unp.next(result)) {
msgpack::object obj(result.get());
obj.convert(&ds);
// use ds
cout << "deserialized: " << ds << endl;
}
// All complete msgpack message is proccessed at this point,
// then continue to read addtional message.
}
}
}
输出:
serialized: [a:1 b:1.11 ... oo:101]
serialized: [a:2 b:2.22 ... oo:202]
deserialized: [a:1 b:1.11 ... oo:101]
deserialized: [a:2 b:2.22 ... oo:202]