(Надеюсь, я правильно понял ваш вопрос, и мой ответ соответствует вашему варианту использования!)
Один из методов сохранения произвольного потока сообщений буфера протокола на диск состоит в том, чтобы определить сообщение-оболочку, в котором все поля определены как repeated
(что подразумевает optional
), а затем, когда вы читаете свои байты, вы получаете экземпляр класса-оболочки и вызовите на нем методы hasX(), чтобы найти то, что у вас есть на самом деле. Проблема с этим подходом в вашем случае заключается в том, что вы не получаете произвольного доступа и реальной потоковой передачи (все сообщения типа Foo
будут вместе, за которыми следуют все Bar
s), и если ваши данные слишком велики, вы не сможете поместиться все в память.
На самом деле вы в основном запрашиваете методологию хранения любых данных таким образом, чтобы их можно было передавать в потоковом режиме или получать произвольный доступ. Это общая проблема, а не проблема, специфичная для протокольных буферов.
Ваши проблемы:
- разграничение записей... (см. примечание)
- ...таким образом, чтобы повреждение можно было обнаружить и либо допустить, либо отремонтировать...
- ... при сохранении индекса для обеспечения произвольного доступа
Вы, вероятно, использовали бы индекс, чтобы разрешить некоторые проверки целостности, но даже для этого требуется механизм, гарантирующий, что индекс и данные соответствуют и остаются синхронизированными.
Следовательно, это может быть не идеальное решение, но один из способов добиться того, что вы хотите, особенно если целостность является проблемой, — это хранить эту информацию в базе данных, которая позволяет хранить двоичные данные и может быстро возвращать эти данные. Тогда вопрос произвольного доступа и целостности данных станет обязанностью поставщика базы данных. Любая традиционная база данных, способная хранить BLOB, сможет это сделать, хотя я бы также рассмотрел возможность хранения в NoSQL, например в MongoDB.
Примечание
Если вы тщательно определите свои протокольные буферы (т. е. вы знаете типы и длину сохраняемых полей), вам не нужно будет разграничивать ваши записи, поскольку их длина никогда не изменится. Однако это нарушило бы одну из особенностей буферов протоколов, а именно их перспективность. Если бы вы разработали .proto
таким образом, чтобы размер сообщения был фиксированным, вы не смогли бы добавлять новые поля и по-прежнему вписываться в тот же формат файла, с уверенностью говоря, что каждое новое сообщение начинается после x байтов.
person
Rich
schedule
09.01.2013