宽字符输入流std::wifstream在反序列化使用std::wofstream序列化的对象时已损坏



我正在尝试为应用程序的对象编写自己的自定义序列化程序和反序列化程序。我知道有很多库,比如boost serialize等,可以随时使用,但我想学习这种序列化和反序列化,因此我做了这项工作。

当我尝试反序列化(使用std::wifstream(我已序列化的对象(使用std::wofstream。甚至连一个班级成员都不能正确阅读。我试图反序列化的前3个成员是bool,但他们从文件流中读取了不正确的值。有人能就这里可能出现的问题提出一些建议吗。谢谢你抽出时间。

应用程序中的Typedefs:

namespace fc
{
#ifdef UNICODE
typedef std::wstring tstring;
typedef std::wfstream tfstream;
typedef std::wofstream tofstream;
typedef std::wifstream tifstream;
typedef std::wstringstream tstringstream;
#else
typedef std::string tstring;
typedef std::fstream tfstream;
typedef std::ofstream tofstream;
typedef std::ifstream tifstream;
typedef std::stringstream tstringstream;
#endif
typedef std::vector<fc::tstring> tstrvec;
typedef std::vector<fc::tstring> tstrvec;
}

正在序列化和反序列化的对象:

struct FastCopyCfg
{
bool mOverwriteFiles;
bool mCopySystemFiles;
bool mCopyHiddenFiles;
fc::tstring mDstFolder;
fc::tstrvec mSrcFiles;
fc::tstrvec mSrcFolders;
fc::tstrvec mIncludeWildcards;
fc::tstrvec mExcludeWildcards;
FastCopyCfg()
{
mOverwriteFiles = false;
mCopySystemFiles = false;
mCopyHiddenFiles = false;
mDstFolder.clear();
mSrcFiles.clear();
mSrcFolders.clear();
mIncludeWildcards.clear();
mExcludeWildcards.clear();
}
template<typename Archive>
void Serialize(Archive& ar, const std::uint16_t = 0)
{
ar & mCopySystemFiles & mCopyHiddenFiles & mOverwriteFiles &
mDstFolder & mSrcFiles & mSrcFolders & mIncludeWildcards & mExcludeWildcards;
}
};

全局插入和提取运算符过载:

void operator >>(IArchive& ar, FastCopyCfg& cfg)
{
cfg.Serialize(ar);
}
void operator <<(OArchive& ar, FastCopyCfg& cfg)
{
cfg.Serialize(ar);
}

Archiver类

class OArchive
{
std::wostream& mStream;
public:
OArchive(std::wostream& stream) :mStream(stream){}
template<typename Val>
OArchive& operator &(std::vector<Val>& vtr)
{
mStream << vtr.size();
std::for_each(vtr.begin(), vtr.end(), [&](auto e) {mStream << e; });
return *this;
}
template<typename DT>
OArchive& operator &(DT& data)
{
mStream << data;
return *this;
}
};
class IArchive
{
std::wistream& mStream;
public:
IArchive(std::wistream& stream) :mStream(stream) {}
template<typename Val>
IArchive& operator &(std::vector<Val>& vtr)
{
std::vector<Val>::value_type vElement;
std::vector<Val>::size_type vSize = 0;
mStream >> vSize;
for (std::vector<Val>::size_type i = 0; i < vSize; i++)
{
mStream >> vElement;
vtr.push_back(vElement);
}
return *this;
}
template<typename DT>
IArchive& operator &(DT& data)
{
try
{
mStream >> data;
}
catch (const std::exception& e)
{
Logger::logDebug("Exception while reading config file: ", e.what());
}
catch (...)
{
}
return *this;
}
};

使用代码进行序列化。我将标志设置为true和false以调试序列化和反序列化。

bool flag = false;
void CFastCopyDlg::OnBnClickedButtonSaveConfiguration()
{
if (flag)
{
fc::tofstream file(fc::CONFIG_FILENAME, fc::tofstream::binary);
OArchive ar(file);
ar << getCopyConfig();
}
else
{
fc::tifstream file(fc::CONFIG_FILENAME, fc::tifstream::binary);
IArchive ar(file);
FastCopyCfg cfg;
ar >> cfg;
}
}

我想我发现了问题。问题是,当文件以二进制模式打开时,不能使用提取运算符>gt;。这里也讨论了类似的话题。请参阅下面的代码,查看问题代码中存在的问题。

class IArchive
{
std::wistream& mStream;
public:
IArchive(std::wistream& stream) :mStream(stream) {}
template<typename Val>
IArchive& operator &(std::vector<Val>& vtr)
{
std::vector<Val>::value_type vElement;
std::vector<Val>::size_type vSize = 0;
mStream >> vSize;
for (std::vector<Val>::size_type i = 0; i < vSize; i++)
{
mStream >> vElement;
vtr.push_back(vElement);
}
return *this;
}
template<typename DT>
IArchive& operator &(DT& data)
{
try
{
mStream >> data; // PROBLEM - BINARY DATA CANNOT BE READ USING >>
}
catch (const std::exception& e)
{
Logger::logDebug("Exception while reading config file: ", e.what());
}
catch (...)
{
}
return *this;
}
};

最新更新