使用boost :: serialization和二进制格式时出现异常

时间:2013-12-12 16:25:58

标签: c++ boost-serialization

我正在尝试通过boost :: serialization实现延迟读取。保存/加载std :: vector很容易,但这需要一次读取整个向量,这在拥有大量对象时是不可行的。

我的想法是将对象计数存储为存档中的第一个对象,然后继续在文件末尾添加geopoints。如果你有一个更好的主意,我会全力以赴。

编写器类似乎工作,读者在构造函数中获得正确的值作为计数,但是当尝试使用运算符>>读取GeoPoint时,它会崩溃:

archive >>p;

输出:

Stream writing 1.25, 3.2
Stream writing 2.5, 6.4
Stream writing 3.75, 9.6
terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  input stream error

这是一个说明我的问题的SSSC:

#include <fstream>
#include <iostream>
#include <stdint.h>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/version.hpp>

using namespace std;

struct GeoPoint {
    GeoPoint() : lon(0), lat(0) {}
    GeoPoint(float _lon, float _lat) : lon(_lon), lat(_lat) {}
    float lon;
    float lat;
};

namespace boost {
    namespace serialization {
        template<class Archive>
        void serialize(Archive& ar, GeoPoint& point, const unsigned version) {
            if (version == 1) {
                ar & point.lon;
                ar & point.lat;
            }
        }
    } //serialization
} //boost
BOOST_CLASS_VERSION(GeoPoint, 1);

class PointReader {
public:
    PointReader(const std::string& path)
        : stream(path.c_str(), ios::in), archive(stream), read(0) {
        archive >>count; //count as the first object in the archive
    }
    PointReader& operator >>(GeoPoint& p) {
        archive >>p; //Crash and then the BT goes into boost files
        ++read;
        return *this;
    }
    bool is_good() {
        return read < count;
    }
private:
    uint32_t read;
    uint32_t count;
    std::ifstream stream;
    boost::archive::binary_iarchive archive;
};

class PointWriter {
public:
    PointWriter(const std::string& path)
        : filepath(path), stream(path.c_str(), ios::out), archive(stream), count(0) { }

    ~PointWriter() {
        if(stream.is_open())
            close();
    }
    void close() {
        stream.close();
        stream.open(filepath.c_str(), ios::out);
        boost::archive::binary_oarchive out(stream);
        out <<count; //write new count as the first object in the archive
        stream.close();
    }
    PointWriter& operator <<(const GeoPoint& p) {
        archive <<p;
        ++count;
        return *this;
    }
private:
    std::string filepath;
    uint32_t count;
    std::ofstream stream;
    boost::archive::binary_oarchive archive;
};

int main(int argc, char** argv) {
    PointWriter streamw("foo2.data");
    for(int a = 1; a < 4; ++a) {
        GeoPoint p;
        p.lon = float(a*1.25f);
        p.lat = float(a*3.2f);
        cout <<"Stream writing " <<p.lon <<", " <<p.lat <<endl;
        streamw <<p;
    }
    streamw.close();

    PointReader streamr("foo2.data");
    uint32_t loops = 0;
    while(streamr.is_good()) {
        GeoPoint p;
        streamr >>p; //Crash
        cout <<"Streamr read " <<p.lon <<", " <<p.lat <<endl;
        if (++loops > 10)
            break;
    }
    return 0;
}

假设您已在/ usr / include中安装了boost,您可以使用以下命令构建它:

g++ -o sssc sssc.cpp -I/usr/include/ -lboost_serialization

0 个答案:

没有答案