c++测试一个文件是否比一组文件旧

发布于 2025-01-10 14:39:22 字数 1220 浏览 2 评论 0原文

我正在为某些数据创建缓存,但当然,如果创建缓存的任何源文件被修改,我希望缓存变得无效。为此,我创建了这个函数:

bool CacheIsValid(
    const std::string& cache_shader_path,
    const std::vector<std::string>& shader_paths)
{
    // This is really messy because of the std stuff, the short of it is:
    // Find the youngest file in the shader paths, then check it against the
    // timestamp of the cached file.
    std::time_t youngest_file_ts = std::time(nullptr);
    for(auto file : shader_paths)
    {
        std::time_t current_timestamp =
            std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(file)));
        double time_diff = difftime(youngest_file_ts, current_timestamp);
        if(time_diff > 0) youngest_file_ts = current_timestamp;
    }

    // All this is doing is comparing the youngest file time stamp with the cache.
    return fs::exists(cache_shader_path)
        && (difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
            std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0);
}

我不知道我做错了什么,但即使输入文件被修改,它也总是返回 true。我正在使用 stat 检查时间戳,并且磁盘上的文件客观上比缓存文件更年轻,我还测试了该函数的输入是否正确,而且确实如此。

I am creating a cache for some data, but of course I want the cache to become invalid if any of the source files from which the cache is made is modified. TO that effect I made this function:

bool CacheIsValid(
    const std::string& cache_shader_path,
    const std::vector<std::string>& shader_paths)
{
    // This is really messy because of the std stuff, the short of it is:
    // Find the youngest file in the shader paths, then check it against the
    // timestamp of the cached file.
    std::time_t youngest_file_ts = std::time(nullptr);
    for(auto file : shader_paths)
    {
        std::time_t current_timestamp =
            std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(file)));
        double time_diff = difftime(youngest_file_ts, current_timestamp);
        if(time_diff > 0) youngest_file_ts = current_timestamp;
    }

    // All this is doing is comparing the youngest file time stamp with the cache.
    return fs::exists(cache_shader_path)
        && (difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
            std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0);
}

I don't know what I did wrong but that is always returning true even when the input files are modified. I am checking the timestamps using stat and the files on disk are objectively younger than the cache file, I also tested that the inputs to this function are correct, and they are.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

盗梦空间 2025-01-17 14:39:22

在我看来,你似乎经历了很多困难,这使得事情变得比实际需要的更加困难。 filesystem::last_write_time 返回一个 time_point1 ,它支持比较。因此,至少据我所知,没有理由对 time_t 进行漫长的转换,然后使用 difftime 进行比较。

如果我理解您正在做的事情的想法,您想要确定该一个文件至少与矢量中指定的任何文件一样新。为了更直接地做到这一点,我会沿着这条总路线编写代码:

bool isNewer(std::string const &file, std::vector<std::string> const &otherFiles) {
    auto newest = std::max_element(otherFiles.begin(), otherFiles.end(), 
        [&](std::string const &a, std::string const &b) {           
            return fs::last_write_time(a) > fs::last_write_time(b);
        });

    return fs::last_write_time(file) >= fs::last_write_time(*newest);
}

我可能误解了您想要完成一个或两个比较的方向,在这种情况下,这可能不正确 - 但如果是这样,请更改比较(s) 以满足您的要求应该是微不足道的。


  1. 其中,someclock 是满足 C++17 的一些指定要求的任意类型,或者是满足 C++20 的 std::chrono::file_clock 的任意类型。

It seems to me that you're jumping through a lot of hoops that make this tremendously more difficult than it needs to be. filesystem::last_write_time returns a time_point<someclock>1 , which supports comparison. As such, at least as far as I can see, there's no reason to do the long, drawn-out conversion to time_t, then using difftime to do the comparison.

If I understand the idea of what you're doing, you want to ascertain that the one file is at least as new as any of the files named in the vector. To do that a bit more directly, I'd write code something along this general line:

bool isNewer(std::string const &file, std::vector<std::string> const &otherFiles) {
    auto newest = std::max_element(otherFiles.begin(), otherFiles.end(), 
        [&](std::string const &a, std::string const &b) {           
            return fs::last_write_time(a) > fs::last_write_time(b);
        });

    return fs::last_write_time(file) >= fs::last_write_time(*newest);
}

I may have misunderstood the direction you want one or both comparisons done, in which case this may not be right--but if so, changing the comparison(s) to match your requirements should be trivial.


  1. where someclock is some arbitrary type that meets a few specified requirements for C++17, or std::chrono::file_clock for C++20.
夏末的微笑 2025-01-17 14:39:22

因为你想找到 youngest_file_ts ->查找正在更改的文件的最近时间戳(更大的数字),但是

double time_diff = difftime(youngest_file_ts, current_timestamp);
if(time_diff > 0) youngest_file_ts = current_timestamp; // find greater number one

在 for 循环之后 youngest_file_ts 是正在更改的文件的最旧时间戳
因此

(difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
          std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0) alway true.

它应该像这样改变

    if (shader_paths.empty()) {
        return false
    } else {
//initialize youngest_file_ts as last_write_time of first element in shader_paths
        std::time_t youngest_file_ts = std::chrono::system_clock::to_time_t(
                 std::chrono::file_clock::to_sys(fs::last_write_time(shader_paths.at(0))); 
        for (auto file : shader_paths)
        {
            std::time_t current_timestamp = std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(file)));
            double time_diff = difftime(youngest_file_ts, current_timestamp);
            if (time_diff < 0) youngest_file_ts = current_timestamp;
        }
        // All this is doing is comparing the youngest file time stamp with the cache.
        return fs::exists(cache_shader_path)
            && (difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0);
    }

due to you want to find youngest_file_ts -> find most recently timestamp (greater number) of a changing file however

double time_diff = difftime(youngest_file_ts, current_timestamp);
if(time_diff > 0) youngest_file_ts = current_timestamp; // find greater number one

after the for loop youngest_file_ts is oldest timestamp of a changing file
therefor

(difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
          std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0) alway true.

it should be change like

    if (shader_paths.empty()) {
        return false
    } else {
//initialize youngest_file_ts as last_write_time of first element in shader_paths
        std::time_t youngest_file_ts = std::chrono::system_clock::to_time_t(
                 std::chrono::file_clock::to_sys(fs::last_write_time(shader_paths.at(0))); 
        for (auto file : shader_paths)
        {
            std::time_t current_timestamp = std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(file)));
            double time_diff = difftime(youngest_file_ts, current_timestamp);
            if (time_diff < 0) youngest_file_ts = current_timestamp;
        }
        // All this is doing is comparing the youngest file time stamp with the cache.
        return fs::exists(cache_shader_path)
            && (difftime(youngest_file_ts, std::chrono::system_clock::to_time_t(
                std::chrono::file_clock::to_sys(fs::last_write_time(cache_shader_path)))) < 0);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文