保存并加载std::chrono::time_point到文件
Saving and loading std::chrono::time_point to file
我试图简单地将当前时间保存并重新加载到文件中。例如:
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
传递到输出流是冗余的。
同样重要的是,请注意二进制序列化是不可移植的:
std::chrono::system_clock::rep
的类型是由实现定义的——唯一的要求是它是一个有符号的算术类型——因此可以从一个编译器/stdlib/build-config更改为下一个- 即使您通过
std::chrono::duration_cast
控制表示类型,积分类型的端序和浮点类型的表示作为一个整体也是特定于体系结构的
因此,只能使用与序列化代码使用相同体系结构/编译器/stdlib/config构建的代码来反序列化数据。
好吧,经过一番折腾,我终于拿到了。
答案是std::time_t
,它是朋友std::chrono::system_clock::from_time_t
和std::chrono::system_clock::to_time_t
。
因此,要保存,您所要做的就是将::now()
转换为time_t
,并将其通过管道传输到文件中。要加载,请使用from_time_t
执行相反的操作。
保存
std::ofstream ofs(solar_system_cache_file,
std::ios::out | std::ios::binary);
if (!ofs.is_open())
return;
auto cache_time = std::chrono::system_clock::now() + 12h;
ofs << std::chrono::system_clock::to_time_t(cache_time);
ofs.close();
加载
std::ifstream ifs(solar_system_cache_file,
std::ios::in | std::ios::binary);
if (!ifs.is_open()) {
return false;
}
std::time_t file_time;
ifs >> file_time;
std::cout << std::ctime(&file_time);
auto cache_valid_time = std::chrono::system_clock::from_time_t(file_time);
ifs.close();
很简单,干杯!
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- CGAL 如何将 std::vector<Point> 点保存到 .xyz 文件中?
- 如何使用QT从文本文件中读取Point(x,y)数据
- Point Cloud Library-CloudViewer showCloud()-传递常量指针-可视化STL文件