![](/img/trans.png)
[英]protocol buffers: how to serialize and deserialize multiple messages into a file (c++)?
[英]C++ serialize multiple objects to one file and deserialize limited number of them
在開始之前,請考慮以下代碼:
一個數據傳輸對象ObjectDTO
class ObjectDTO {
public:
int id;
string string1;
string string2;
string string3;
int code1;
vector<string> stringList1;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &archive, const unsigned int version) {
archive & id;
archive & string1;
archive & string2;
archive & string3;
archive & code1;
archive & stringList1;
}
序列化
void OutputStreamService::writeReportsToFile(vector<ObjectDTO> objects, int filename){
ofstream outputFileStream(to_string(filename));
boost::archive::binary_oarchive outputArchive(outputFileStream);
outputArchive << objects;
}
反序列化
vector<ObjectDTO> InputStreamService::readObjects() {
ifstream inputFileStream(to_string(fileNumber++));
boost::archive::binary_iarchive inputArchive(inputFileStream);
vector<ObjectDTO> objects;
inputArchive >> objects;
return objects;
}
我正在使用Boost Serialization C ++庫來序列化ObjectDTO
的vector
並在以后讀取它。
Supose我生成了30GB的隨機ObjectDTO
並將其保存到同一個文件中
我如何只閱讀其中一些以避免達到內存限制?
我正在使用Boost Serialization,因為它是我找到解決第一個問題的簡單方法, 但如果有必要我可以改為任何其他方法!
使用Google協議緩沖區,有用於序列化的CodedOutputStream類和用於反序列化的CodedInputStream。
CodedOutputStream方法之一是WriteVarint32,它允許寫入一個可以用作流中索引的數字。
在CodeInputStream中有相應的ReadVarint32方法,例如。
連載:
char text[[]] = "Hello world!";
coded_output->WriteVarint32(strlen(text));
coded_output->WriteRaw(text, strlen(text));
反序列化:
uint32 size;
coded_input->ReadVarint32(&size);
char* text = new char[size + 1];
coded_input->ReadRaw(buffer, size);
最后一行允許您從給定索引開始讀取序列化流的內容。
以下是我在開始時使用給定長度序列化/反序列化流的兩種方法。
template < class T>
void TProtoBufSerializer::SerializeImplementation(const T& protoBuf, std::vector<char>& buffer )
{
int bufLength = protoBuf.ByteSize() + google::protobuf::io::CodedOutputStream::VarintSize32(protoBuf.ByteSize());
buffer.resize(bufLength);
google::protobuf::io::ArrayOutputStream arrayOutput(&buffer[0], bufLength);
google::protobuf::io::CodedOutputStream codedOutput(&arrayOutput);
codedOutput.WriteVarint32(protoBuf.ByteSize());
protoBuf.SerializeToCodedStream(&codedOutput);
}
template < class T>
bool TProtoBufSerializer::DeSerializeImplementation(std::vector<char>& buffer, T& protoBuf )
{
bool deserialized = false;
google::protobuf::io::ArrayInputStream arrayInput(&buffer[0],buffer.size());
google::protobuf::io::CodedInputStream codedInput(&arrayInput);
unsigned int object_size;
bool header_readed = codedInput.ReadVarint32(&object_size);
if(header_readed && object_size > 0)
{
if( buffer.size() >= codedInput.CurrentPosition() + object_size )
{
google::protobuf::io::CodedInputStream::Limit limit = codedInput.PushLimit(object_size);
if(protoBuf.ParseFromCodedStream(&codedInput))
{
std::vector<char>::iterator it = buffer.begin();
std::advance(it,codedInput.CurrentPosition());
std::move(it,buffer.end(),buffer.begin() );
buffer.resize(buffer.size() - codedInput.CurrentPosition());
deserialized = true;
}
else
{
throw TProtoBufSerializerPayloadException();
}
codedInput.PopLimit(limit);
}
}
else
{
//varint32 which is used in header is at the most 5 bytes long,
//if given buffer is 5 bytes or more long and header still cannot be decoded - raise exception
if(buffer.size() >= 5)
{
throw TProtoBufSerializerHeaderException();
}
}
return deserialized;
}
我解決丟棄升壓序列化和矢量有利於與普通的舊C數組的++問題write
和read
上ofstream
和ifstream
分別。
我的OutputStreamService writeObjectsToFile結束如下:
void OutputStreamService::writeObjectssToFile(ObjectDTO * objects, int filename){
ofstream outputFileStream(to_string(filename), std::ios::binary);
outputFileStream.write((char *)&objects, sizeof(objects));
}
和帶有readObjects的InputStreamService:
ObjectDTO * InputStreamService::readObjects() {
ifstream inputFileStream(to_string(fileNumber++), std::ios::binary);
ObjectDTO objects[10];
inputFileStream.read((char *)&objects, sizeof(objects));
return objects;
}
這樣我可以定義10
或任何其他整數作為我想要讀入的對象的數量。
為了解決mais問題,我現在可以計算我的內存可以處理的對象的aprox數量,然后限制讀取次數!
泰!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.