Предположим, ваш Protobuf message
выглядит следующим образом:
message Object
{
... = 1;
... = 2;
... = 3;
}
Затем в том же файле ввести более message
1, который представляет собой совокупность этих Object
с.
message Objects
{
repeated Object array = 1;
}
Таким образом, если у вас есть много элементов, вы можете просто использовать Objects
и использовать SerializeAsString()
на самом Objects
. Это позволит сэкономить ваши усилия на сериализацию отдельных Object
отдельно и размещение собственного ограничителя ручной работы. Вы можете сериализовать все Object
с использованием одного экземпляра Objects
.
При таком подходе вы делегируете все разбор & сериализуете работу также в библиотеку Protobuf. Я использую это в своем проекте, и это работает как шарм.
Кроме того, разумное использование Objects
также позволит избежать дополнительных копий Object
. Вы можете добавлять элементы к ним и получать доступ с помощью индексации. Поле protobufs repeated
совместимы с C++ 11, поэтому вы можете использовать его с итераторами или расширенным циклом for
.
Важно отметить, что, когда вы сохраняете вывод Objects::SerializeAsString()
в файл, вы должны первым вход длина этого string
с последующим фактическим сериализованном строки. Во время чтения вы можете прочитать длину сначала, за которой следуют общие байты. Для простоты использования, я продлил std::fstream
и перегружен ниже методы:
struct fstreamEncoded : std::fstream
{
// other methods
void // returns `void` to avoid multiple `<<` in a single line
operator<< (const string& content)
{ // below casting would avoid recursive calling of this method
// adding `length() + 1` to include the protobuf's last character as well
static_cast<std::fstream&>(*this) << (content.length() + 1) << "\n" << content << std::endl;
}
string
getline()
{
char length_[20] = {};
std::istream::getline(length_, sizeof(length_) - 1);
if(*length_ == 0)
return "";
const size_t length = std::atol(length_); // length of encoded input
string content(length, 0); // resize the `string`
read(&content[0], length); // member of `class istream`
return content;
}
}
Выше всего лишь иллюстрация. Вы можете следить в соответствии с потребностями вашего проекта.
Как насчет префикса потока строк с информацией о длине? – Arunmu
Я мог бы префикс sizeof (int) перед каждой строкой. Похоже, он должен работать. Я попытаюсь опубликовать результаты, если будет работать – Mugen