从 std::fstream 反序列化
使用类似的方法从文件中读取序列化数据(已知格式+字节序)是否有什么特别糟糕或天真的事情?我并不担心可移植性,实际上它只会由我使用。我知道一个问题是尝试提取到非打包的 POD 结构,尽管我总是可以为每个这样的结构定义一个单独的 operator>
。
template<typename T> inline std::fstream& operator> (std::fstream& fs, T& i) {
static_assert(std::is_pod<T>::value, "Not POD");
fs.read(reinterpret_cast<char*>(&i), sizeof i);
return fs;
}
template<typename T> inline std::fstream& operator> (std::fstream& fs, std::vector<T>& v) {
static_assert(std::is_pod<T>::value, "Not POD");
fs.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size());
return fs;
}
template<typename T> inline std::fstream& operator> (std::fstream& fs, std::vector<std::vector<T>>& v) {
for (auto& i : v)
fs > i;
return fs;
}
inline std::fstream& operator> (std::fstream& fs, std::string& s) {
fs.read(reinterpret_cast<char*>(&s[0]), s.size());
return fs;
}
std::fstream f("file", std::ifstream::in | std::ifstream::out | std::ifstream::binary);
int i;
char j;
std::vector<std::vector<char>> vec(5, std::vector<char>(8));
f > i > j > vec;
Is there anything particularly bad or naive about reading serialized data (of a known format + endianness) from a file using something like this? I'm not worried about portability and realistically it would only be used by me. I know one issue would be attempting to extract to a non-packed POD struct, although I can always define a separate operator>
for each such struct.
template<typename T> inline std::fstream& operator> (std::fstream& fs, T& i) {
static_assert(std::is_pod<T>::value, "Not POD");
fs.read(reinterpret_cast<char*>(&i), sizeof i);
return fs;
}
template<typename T> inline std::fstream& operator> (std::fstream& fs, std::vector<T>& v) {
static_assert(std::is_pod<T>::value, "Not POD");
fs.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size());
return fs;
}
template<typename T> inline std::fstream& operator> (std::fstream& fs, std::vector<std::vector<T>>& v) {
for (auto& i : v)
fs > i;
return fs;
}
inline std::fstream& operator> (std::fstream& fs, std::string& s) {
fs.read(reinterpret_cast<char*>(&s[0]), s.size());
return fs;
}
std::fstream f("file", std::ifstream::in | std::ifstream::out | std::ifstream::binary);
int i;
char j;
std::vector<std::vector<char>> vec(5, std::vector<char>(8));
f > i > j > vec;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定你在问什么。您发布的代码无法读取
“已知格式或字节顺序”的序列化数据。它从以下位置复制字节
文件到任何地方,这可能会导致未定义的行为,并且是
除非出现一些奇怪的情况,否则不太可能产生正确的值
幸运的是,“已知格式”与内部使用的格式完全一致
在你的机器上。我遇到很多情况,其实这很可能会导致
程序崩溃;想想如果你的结构会发生什么
例如,尝试读取包含指针的内容。
我可能会添加重载 '>'因为这是可怕的超载滥用;如果
如果您想读取特殊格式,合乎逻辑的方法是
定义相应的类(例如
ixdrstream
),并重载'>>'为了它。 (
ixdrstream
可能源自std::basic_ios
,当然,并且几乎肯定会使用标准
streambuf
用于实际输入。)当然,您永远不会在
std::fstream
上重载,而是在std::istream
(或std::ostream
用于输出)。 (FWIW,我不认为我曾经使用过
std::fstream
。流习语确实不是支持优雅地混合读写。)
I'm not sure what you're asking. The code you post doesn't read
serialized data "of a known format or endianness". It copies bytes from
the file to where ever, which could result in undefined behavior, and is
very unlikely to result in the correct values unless by some weird bit
of luck, the "known format" corresponds exactly to that used internally
on your machine. I a lot of cases, in fact, it will probably cause the
program to crash; think of what might happen if the structure you're
trying to read contains a pointer, for example.
I might add that overloading '>' for this is horrible overload abuse; if
you want to read a special format, the logical way to go about it is to
define a corresponding class (
ixdrstream
, for example), and overload'>>' for it. (
ixdrstream
will probably derive fromstd::basic_ios<char>
, of course, and will almost certainly use thestandard
streambuf
for actual input.)And of course, you never overload on
std::fstream
, but rather onstd::istream
(orstd::ostream
for output). (FWIW, I don't thinkI've ever used an
std::fstream
. The stream idiom really doesn'tsupport mixing reads and writes elegantly.)