如何以跨平台的方式获取文件的修改时间?

5
稳定的 MetadataExt 特质提供了一些基本功能,但它不能在 Windows 上工作。
我还看到了关于 I/O 改革的 这个 RFC,但现在我完全迷惑了。难道不是因为 Rust 的 I/O 问题反馈非常强烈才导致我们需要花费如此长的时间来获取 1.0 稳定版本吗?
为什么 实验性的 std::os::unix::fs::MetadataExt 特质稳定了,而相同功能没有跨平台解决方案?
是否有一些我没有找到的标准包可用于此目的? 这个问题涉及 Rust 1.3.0。
3个回答

11
首先,有一个相关的crate:filetime(由Vladimir Matveev指出)。需要注意的是,该crate中的FileTime::seconds方法是平台特定的。
其次,1.0版本关注于构建语言的基础,而不是完整的标准库。虽然它已经包含了很多你通常期望的内容,但仍有一些缺失,现在(1.3版)仍然存在。部分原因是核心团队非常谨慎,对于他们承诺支持的内容非常认真,考虑到向后兼容性。
第三,在MetadataExt方面,它不是实验性的,而是稳定的。只是碰巧它是平台特定的。
第四,MetadataExt实际上是一个误导。真正的问题在于,rustdoc是编译器的一种后处理过程,插入在类型检查完成后。这使得它在宏展开之后执行。这很重要,因为正是在宏展开期间解析平台特定的#[cfg(...)]属性。这一点很重要,因为这是语言处理平台特定代码的方式。
因此,文档仅针对您具体定位的平台构建。官方网站上的文档都是针对Linux的。因此,不会显示任何与Windows相关的内容。现在,如果您下载Windows编译器,则会附带一组文档,并且这些文档会针对Windows。如果您打开这些文档并进行搜索,将找到std::os::windows::fs::MetadataExt,它看起来像这样:
pub trait MetadataExt {
    fn file_attributes(&self) -> u32;
    fn creation_time(&self) -> u64;
    fn last_access_time(&self) -> u64;
    fn last_write_time(&self) -> u64;
    fn file_size(&self) -> u64;
}

(由于明显的原因,我不能仅仅提供此链接。)

顺便说一下,您提供的不是RFC; 它是RFC存储库上的问题。它用于跟踪应编写RFC的事项。

因此,为了总结这一切:您可以使用上述垫片或者编写特定于平台的代码,这很可能会归结为Windows的一个路径和其他所有内容的一个路径,使用两个不同的 MetadataExt 特征。要注意的一件事是,这两个系统使用不同的时期,这意味着时间不能直接进行比较。UNIX使用1970年1月1日的时期,Windows使用1601年1月1日。

最简单的方法可能只是使用上面提到的垫片。


这个可以使用filetime库,它提供了跨平台访问各种文件时间戳的功能。 - Vladimir Matveev
不需要更多的依赖来完成如此简单的事情,谢谢。 - Gubatron

3

Metadata::modified 返回一个 SystemTime,它需要使用 UNIX_EPOCH 作为时间锚点来了解有关 SystemTime 的信息,因为“无法直接检查 SystemTime”。因此,Metadata::modified 不是跨平台的。 - Sylvester Kruin
它不是跨平台的吗?UNIX_EPOCH 在所有系统上都被定义为“1970年01月01日00:00:00 UTC”。 - Mark
这绝对是问题的正确答案。 - Simon Edlund

2
这是我在util模块中的代码。传入路径,获取修改后的Unix时间戳(以秒为单位)。
use std::fs;
use std::time::UNIX_EPOCH;

pub fn file_modified_time_in_seconds(path: &str) -> u64 {
    fs::metadata(path)
    .unwrap()
    .modified()
    .unwrap()
    .duration_since(UNIX_EPOCH)
    .unwrap()
    .as_secs()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接