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

c++ testing if one file is older than a set of files

我正在为一些数据创建一个缓存,但是我当然希望缓存在创建缓存的任何源文件被修改时失效。为此,我做了这个功能:

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 检查时间戳,磁盘上的文件客观上比缓存文件年轻,我还测试了此函数的输入是否正确,它们是正确的。

由于您想查找 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);
    }

在我看来,您正在经历很多困难,这使得这比需要的困难得多。 filesystem::last_write_time returns a time_point<someclock>1 ,支持比较。因此,至少据我所知,没有理由进行长时间的 drawn-out 转换为 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);
}

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


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