从 std::fstream 反序列化

发布于 2024-12-13 09:27:02 字数 1263 浏览 0 评论 0原文

使用类似的方法从文件中读取序列化数据(已知格式+字节序)是否有什么特别糟糕或天真的事情?我并不担心可移植性,实际上它只会由我使用。我知道一个问题是尝试提取到非打包的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

榕城若虚 2024-12-20 09:27:02

我不确定你在问什么。您发布的代码无法读取
“已知格式或字节顺序”的序列化数据。它从以下位置复制字节
文件到任何地方,这可能会导致未定义的行为,并且是
除非出现一些奇怪的情况,否则不太可能产生正确的值
幸运的是,“已知格式”与内部使用的格式完全一致
在你的机器上。我遇到很多情况,其实这很可能会导致
程序崩溃;想想如果你的结构会发生什么
例如,尝试读取包含指针的内容。

我可能会添加重载 '>'因为这是可怕的超载滥用;如果
如果您想读取特殊格式,合乎逻辑的方法是
定义相应的类(例如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 from
std::basic_ios<char>, of course, and will almost certainly use the
standard streambuf for actual input.)

And of course, you never overload on std::fstream, but rather on
std::istream (or std::ostream for output). (FWIW, I don't think
I've ever used an std::fstream. The stream idiom really doesn't
support mixing reads and writes elegantly.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文