Increase the end of file serialization

I serialize multiple objects to a binary archive using Boost. When reading these objects from binary_iarchive , is there a way to find out how many objects are in the archive or just a way to detect the end of the archive?

The only way I found is to use try-catch to detect a thread exception. Thanks in advance.

+8
boost eof boost-serialization
source share
4 answers

I can come up with several approaches:

  • Serialize STL containers to / from your archive (see documentation ). The archive will automatically track the number of objects in containers.

  • Serialize the count variable before serializing your objects. When reading your objects, you will know in advance how many objects you expect to read.

  • Perhaps the last object has a special meaning that acts as a kind of sentinel signal that indicates the end of the list of objects. Perhaps you can add an isLast member isLast to the object.

  • This is not very beautiful, but you can have a separate "index file" next to your archive, which stores the number of objects in the archive.

  • Use the tellp position of the base stream object to determine if you are at the end of the file:

Example (sketch only, not verified):

 std::streampos archiveOffset = stream.tellg(); std::streampos streamEnd = stream.seekg(0, std::ios_base::end).tellg(); stream.seekg(archiveOffset); while (stream.tellp() < streamEnd) { // Deserialize objects } 

This may not work with XML archives.

+6
source share

Do you have all your objects when you start serialization? If not, you are "abusing" boost serialization - it is not intended to be used that way. However, I use it this way, using try catch to find the end of the file, and it works for me. Just hide it somewhere in the implementation. Beware though, if you use it that way, you need to either not serialize pointers or disable pointer tracking.

If you already have all the objects, see Emile's answer. All of them are valid approaches.

0
source share
 std::istream* stream_; boost::iostreams::filtering_streambuf<boost::iostreams::input>* filtering_streambuf_; ... stream_ = new std::istream(memoryBuffer_); if (stream_) { filtering_streambuf_ = new boost::iostreams::filtering_streambuf<boost::iostreams::input>(); if (filtering_streambuf_) { filtering_streambuf_->push(boost::iostreams::gzip_decompressor()); filtering_streambuf_->push(*stream_); archive_ = new eos::portable_iarchive(*filtering_streambuf_); } } 

using zip when reading data from archives, and filtering_streambuf has a method like

 std::streamsize std::streambuf::in_avail() Get number of characters available to read 

so I check the end of the archive as

 bool IArchiveContainer::eof() const { if (filtering_streambuf_) { return filtering_streambuf_->in_avail() == 0; } return false; } 

It does not help to know how many objects are left in the archive last, but it helps to determine their end. (I use eof test only in a unit test to serialize / deserialize my classes / structures - to make sure that I read everything I write)

0
source share

you just read the byte from the file.

If you do not get to the end,

enter back byte.

-one
source share

All Articles