我正在尝试通过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