c++ - 保存和加载 std::chrono::time_point 到文件

标签 c++ c++11 c++14 fstream c++-chrono

我正在尝试简单地保存并重新加载文件中的当前时间。例如:

std::ifstream ifs(solar_system_cache_file,
        std::ios::in | std::ios::binary);

if (!ifs.is_open()) {
    return false;
}

std::chrono::system_clock::time_point cache_valid_time;
ifs >> cache_valid_time;

if (std::chrono::system_clock::now() < cache_valid_time) {
    std::cout << "Cache is VALID." << std::endl;
}
ifs.close();
return true;

std::ofstream ofs(solar_system_cache_file,
        std::ios::out | std::ios::binary);

if (!ofs.is_open())
    return;

ofs << std::chrono::system_clock::now() + 12h;
ofs.close();

这种事情并不复杂,但我已经四处寻找了几个小时,但找不到相关信息。有一些关于如何使用 duration_cast<long, std::milli> 进行转换的示例,但是 std::chrono非常复杂且难以导航(和消化)。

简而言之,我认为我需要将当前时间转换为 long (或一些类似的大类型)并保存。反序列化时间时,我只需要将其转换回 time_point .这听起来很容易,但我做不到。

最后,简单地将时间输入 fstream给出通常的 invalid operands to binary expression错误。

感谢任何帮助,或指向好的教程/指南的链接。 谢谢

最佳答案

如果您想要二进制序列化,请不要使用格式化文本例程来实现您的序列化。 :-]

时钟的 time_point 只是算术类型的包装器,算术类型是自时钟纪元以来经过的某个时间单位的周期数。您真正需要做的就是将该算术值序列化为二进制形式:

保存

using namespace std::chrono_literals;
using clock_t = std::chrono::system_clock;

std::ofstream ofs{ solar_system_cache_file, std::ios::binary };
if (!ofs.is_open()) {
    return;
}

auto const cache_time = (clock_t::now() + 12h).time_since_epoch().count();
ofs.write(reinterpret_cast<char const*>(&cache_time), sizeof cache_time);
ofs.close();

正在加载

std::ifstream ifs{ solar_system_cache_file, std::ios::binary };
if (!ifs.is_open()) {
    return false;
}

clock_t::rep file_time_rep;
if (!ifs.read(reinterpret_cast<char*>(&file_time_rep), sizeof file_time_rep)) {
    return false;
}
ifs.close();

clock_t::time_point const cache_valid_time{ clock_t::duration{ file_time_rep } };
std::time_t const file_time{ clock_t::to_time_t(cache_valid_time) };
std::cout << std::ctime(&file_time);

请注意,将 openmode::in 传递给输入流并将 openmode::out 传递给输出流是多余的。

此外,重要的是,请注意二进制序列化不可移植:

  1. std::chrono::system_clock::rep 的类型是实现定义的——唯一的要求是它是一个带符号的算术类型——因此可以从一个编译器/stdlib/build 改变配置到下一个。
  2. 即使您通过 std::chrono::duration_cast 控制表示类型,整数类型的字节顺序和浮点类型的表示作为一个整体也是特定于体系结构的。

因此,您只能依靠使用与序列化代码相同的体系结构/编译器/stdlib/config 构建的代码来反序列化数据。

关于c++ - 保存和加载 std::chrono::time_point 到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36963373/

相关文章:

c++ - 设置开始迭代器时无效使用非静态数据成员

c++ - 另一种类型的智能指针,例如带有弱引用的 unique_ptr?

c++ - 筛选在 Opencv 2.4.6 ubuntu 中的实现

c++ - 如何在一个 vs2008 项目中将库与 __stdcall 和 __cdecl 结合起来

c++ - 绕过SDL2中的 "int main(int argc, char** argv)"

c++ - 三字母仍然有效 C++ 吗?

c++ - 为什么在 CentOS 7 上选择了错误的 GCC 7.2 libstdc++ ABI?

c++ - 实现是否应该防止逗号重载?

c++ - 强类型 C++0x 枚举比较

c++ - 为什么 C++11 不支持匿名结构,而 C11 支持?