促进序列化,需要帮助理解
Boost Serialization, need help understanding
我在下面附上了 boost 示例序列化代码。我看到他们创建了一个输出存档,然后将 class 写入输出存档。然后,他们创建一个输入存档并从输入存档读取到一个新的 class 实例中。我的问题是,输入存档如何知道它的读取数据来自哪个输出存档?例如,假设我有多个输出档案。创建的输入存档如何知道要从哪个输出存档读取?我不明白这是怎么回事。感谢您的帮助!
#include <fstream>
// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
private:
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & degrees;
ar & minutes;
ar & seconds;
}
int degrees;
int minutes;
float seconds;
public:
gps_position(){};
gps_position(int d, int m, float s) :
degrees(d), minutes(m), seconds(s)
{}
};
int main() {
// create and open a character archive for output
std::ofstream ofs("filename");
// create class instance
const gps_position g(35, 59, 24.567f);
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << g;
// archive and stream closed when destructors are called
}
// ... some time later restore the class instance to its orginal state
gps_position newg;
{
// create and open an archive for input
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> newg;
// archive and stream closed when destructors are called
}
return 0;
}
示例 2
void save_load_with_binary_archive()
{
// binary archive with stringstream
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
Camera cam;
cam.id = 100;
cam.name = "new camera";
cam.pos = 99.88;
oa & (cam);
// get binary content
std::string str_data = oss.str();
std::istringstream iss(str_data);
boost::archive::binary_iarchive ia(iss);
Camera new_cam;
ia & (new_cam);
std::cout << new_cam << std::endl;
}
正如其他人所说,您可以根据现有内容设置流。这可以来自内存(例如 istringstream
)或来自文件(例如 ifstream
)。
重要的是您流式传输的内容。这是您修改后的第一个示例,以保存 10 个不同的流,可以按任何顺序读回,或者根本不读回:
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <fstream>
#include <iostream>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position {
public:
gps_position(int d = 0, int m = 0, float s = 0)
: degrees(d)
, minutes(m)
, seconds(s) {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned )
{
ar& degrees& minutes& seconds;
}
int degrees;
int minutes;
float seconds;
friend std::ostream& operator<<(std::ostream& os, gps_position const& gps) {
return os << gps.degrees << "°" << gps.minutes << "′" << gps.seconds << "″";
}
};
int main() {
for (int i = 1; i <= 10; ++i) {
gps_position const g(7 * i, 12 * i - 1, i * 24.567f / 5);
// save data to archive
{
std::ofstream ofs("filename" + std::to_string(i));
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << g;
}
}
for (int i = 10; i > 0; --i) {
// create and open an archive for input
std::ifstream ifs("filename" + std::to_string(i));
boost::archive::text_iarchive ia(ifs);
gps_position newg;
ia >> newg;
std::cout << " i:" << i << " - " << newg << "\n";
}
}
版画
i:10 - 70°119′49.134″
i:9 - 63°107′44.2206″
i:8 - 56°95′39.3072″
i:7 - 49°83′34.3938″
i:6 - 42°71′29.4804″
i:5 - 35°59′24.567″
i:4 - 28°47′19.6536″
i:3 - 21°35′14.7402″
i:2 - 14°23′9.8268″
i:1 - 7°11′4.9134″
完成后,每个流的内容将保存在文件中:
==> filename1 <==
22 serialization::archive 19 0 0 7 11 4.913399696e+00
==> filename10 <==
22 serialization::archive 19 0 0 70 119 4.913399887e+01
==> filename2 <==
22 serialization::archive 19 0 0 14 23 9.826799393e+00
==> filename3 <==
22 serialization::archive 19 0 0 21 35 1.474019909e+01
==> filename4 <==
22 serialization::archive 19 0 0 28 47 1.965359879e+01
==> filename5 <==
22 serialization::archive 19 0 0 35 59 2.456699944e+01
==> filename6 <==
22 serialization::archive 19 0 0 42 71 2.948039818e+01
==> filename7 <==
22 serialization::archive 19 0 0 49 83 3.439379883e+01
==> filename8 <==
22 serialization::archive 19 0 0 56 95 3.930719757e+01
==> filename9 <==
22 serialization::archive 19 0 0 63 107 4.422060013e+01
SIDENOTE: The comment // archive and stream closed when destructors are called
was misleading in your question code because ofs
was declared outside that scope block. This difference is important.
我在下面附上了 boost 示例序列化代码。我看到他们创建了一个输出存档,然后将 class 写入输出存档。然后,他们创建一个输入存档并从输入存档读取到一个新的 class 实例中。我的问题是,输入存档如何知道它的读取数据来自哪个输出存档?例如,假设我有多个输出档案。创建的输入存档如何知道要从哪个输出存档读取?我不明白这是怎么回事。感谢您的帮助!
#include <fstream>
// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
private:
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & degrees;
ar & minutes;
ar & seconds;
}
int degrees;
int minutes;
float seconds;
public:
gps_position(){};
gps_position(int d, int m, float s) :
degrees(d), minutes(m), seconds(s)
{}
};
int main() {
// create and open a character archive for output
std::ofstream ofs("filename");
// create class instance
const gps_position g(35, 59, 24.567f);
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << g;
// archive and stream closed when destructors are called
}
// ... some time later restore the class instance to its orginal state
gps_position newg;
{
// create and open an archive for input
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> newg;
// archive and stream closed when destructors are called
}
return 0;
}
示例 2
void save_load_with_binary_archive()
{
// binary archive with stringstream
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
Camera cam;
cam.id = 100;
cam.name = "new camera";
cam.pos = 99.88;
oa & (cam);
// get binary content
std::string str_data = oss.str();
std::istringstream iss(str_data);
boost::archive::binary_iarchive ia(iss);
Camera new_cam;
ia & (new_cam);
std::cout << new_cam << std::endl;
}
正如其他人所说,您可以根据现有内容设置流。这可以来自内存(例如 istringstream
)或来自文件(例如 ifstream
)。
重要的是您流式传输的内容。这是您修改后的第一个示例,以保存 10 个不同的流,可以按任何顺序读回,或者根本不读回:
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <fstream>
#include <iostream>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position {
public:
gps_position(int d = 0, int m = 0, float s = 0)
: degrees(d)
, minutes(m)
, seconds(s) {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned )
{
ar& degrees& minutes& seconds;
}
int degrees;
int minutes;
float seconds;
friend std::ostream& operator<<(std::ostream& os, gps_position const& gps) {
return os << gps.degrees << "°" << gps.minutes << "′" << gps.seconds << "″";
}
};
int main() {
for (int i = 1; i <= 10; ++i) {
gps_position const g(7 * i, 12 * i - 1, i * 24.567f / 5);
// save data to archive
{
std::ofstream ofs("filename" + std::to_string(i));
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << g;
}
}
for (int i = 10; i > 0; --i) {
// create and open an archive for input
std::ifstream ifs("filename" + std::to_string(i));
boost::archive::text_iarchive ia(ifs);
gps_position newg;
ia >> newg;
std::cout << " i:" << i << " - " << newg << "\n";
}
}
版画
i:10 - 70°119′49.134″
i:9 - 63°107′44.2206″
i:8 - 56°95′39.3072″
i:7 - 49°83′34.3938″
i:6 - 42°71′29.4804″
i:5 - 35°59′24.567″
i:4 - 28°47′19.6536″
i:3 - 21°35′14.7402″
i:2 - 14°23′9.8268″
i:1 - 7°11′4.9134″
完成后,每个流的内容将保存在文件中:
==> filename1 <==
22 serialization::archive 19 0 0 7 11 4.913399696e+00
==> filename10 <==
22 serialization::archive 19 0 0 70 119 4.913399887e+01
==> filename2 <==
22 serialization::archive 19 0 0 14 23 9.826799393e+00
==> filename3 <==
22 serialization::archive 19 0 0 21 35 1.474019909e+01
==> filename4 <==
22 serialization::archive 19 0 0 28 47 1.965359879e+01
==> filename5 <==
22 serialization::archive 19 0 0 35 59 2.456699944e+01
==> filename6 <==
22 serialization::archive 19 0 0 42 71 2.948039818e+01
==> filename7 <==
22 serialization::archive 19 0 0 49 83 3.439379883e+01
==> filename8 <==
22 serialization::archive 19 0 0 56 95 3.930719757e+01
==> filename9 <==
22 serialization::archive 19 0 0 63 107 4.422060013e+01
SIDENOTE: The comment
// archive and stream closed when destructors are called
was misleading in your question code becauseofs
was declared outside that scope block. This difference is important.