我正在将一些代码从boost::filesystem
转换为std::filesystem
。以前的代码使用boost::filesystem::last_write_time()
,它返回一个time_t
,所以直接比较我已经持有的time_t
对象非常简单。顺便说一句,我持有的这个time_t
是从很久以前保存的文件内容中读取的,所以我不得不使用这个“自unix时代以来的时间”类型。
std::filesystem::last_write_time
返回一个std::filesystem::file_time_type
。是否有一种可移植的方法将file_time_type
转换为time_t
,或者以其他方式对这两个对象进行可移植性比较?
#include <ctime>
#include <filesystem>
std::time_t GetATimeInSecondsSince1970Epoch()
{
return 1207609200; // Some time in April 2008 (just an example!)
}
int main()
{
const std::time_t time = GetATimeInSecondsSince1970Epoch();
const auto lastWriteTime = std::filesystem::last_write_time("c:\\file.txt");
// How to portably compare time and lastWriteTime?
}
编辑:请注意,last_write_time
声明它假设时钟是实现to_time_t
函数的std::chrono::system_clock
。这个假设并不总是正确的,也不在我的平台(VS2017)上。
发布于 2022-06-02 14:18:53
这是我在Windows、MacOS和Linux上使用的填充程序。不幸的是,Clang和GCC还没有file_clock支持,而且对Windows的支持也绑定到最近的10+版本中。请参阅:https://github.com/microsoft/STL/issues/1911
// Copied from Boost: filesystem/src/operations.cpp
// these constants come from inspecting some Microsoft sample code
#ifdef _WIN32
inline std::time_t to_time_t(FILETIME const& ft) BOOST_NOEXCEPT {
uint64_t t = (static_cast<uint64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
t -= 116444736000000000ull;
t /= 10000000u;
return static_cast<std::time_t>(t);
}
#else
// Copied from Stackoverflow
template<typename TP>
std::time_t to_time_t(TP tp) {
using namespace std::chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
return system_clock::to_time_t(sctp);
}
#endif
// Use this polyfill until everyone supports C++20
// This code is highly depended on the implementation
time_t PortableLastWriteTime(const std::string& File) {
#ifdef _WIN32
// We cannot use the C++20 and filesystem due to this incompatibility/error: https://github.com/microsoft/STL/issues/1911
// This problem makes this request to fail on Windows older than Windows 10 (1903) and somehow Server 2019 completely
HANDLE handle = CreateFile(File.c_str(), GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
FILETIME lwt;
if (!::GetFileTime(handle, NULL, NULL, &lwt)) {
CloseHandle(handle);
return 0;
}
CloseHandle(handle);
return to_time_t(lwt);
#elif __GLIBCXX__
auto ftime = std::filesystem::last_write_time(File);
return to_time_t(ftime);
#elif _LIBCPP_VERSION
auto ftime = std::filesystem::last_write_time(File);
return decltype(ftime)::clock::to_time_t(ftime);
#elif __CORRECT_CPP20_VERSION
// This is the correct C++20 usage when compilers have full compatibility
const auto fileTime = std::filesystem::last_write_time(File);
const auto systemTime = std::chrono::clock_cast<std::chrono::system_clock>(fileTime);
const auto time = std::chrono::system_clock::to_time_t(systemTime);
return time;
#else
Unsupported compiler !
#endif
}
https://stackoverflow.com/questions/51273205
复制相似问题