Reputation: 35216
The stable MetadataExt
trait offers some basic functionality for this purpose, but it doesn't work on Windows.
I also see this RFC on the topic of I/O reform but now I'm totally confused. Wasn't the reason we took so long to get a 1.0 stable because of the absolutely epic feedback on the I/O story for Rust?
Why are the experimental std::os::unix::fs::MetadataExt
traits in stable, when there is no cross platform story for the same functionality?
Is there some standard crate that I haven't found for this purpose? This question refers to Rust 1.3.0.
Upvotes: 6
Views: 6747
Reputation: 6489
Here's what I have in my util's module. Pass the path and get the modified unix timestamp in seconds.
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()
}
Upvotes: 4
Reputation: 11933
Starting with Rust 1.10, there is a Metadata::modified
method to get the modification time.
Upvotes: 4
Reputation: 59155
First of all, there is a crate for this: filetime
(pointed out by Vladimir Matveev). Just be aware that the FileTime::seconds
method in that crate is platform specific.
Secondly, 1.0 was about building the foundation for the language, not the complete standard library. It shipped with a lot of things that you might normally expect missing. Quite a few are still missing (as of 1.3). Part of this is is that the core team are very conservative about what they'll promise to support, given how seriously they're taking backward compatibility.
Third, MetadataExt
isn't experimental. It's stable. It just happens to be platform-specific.
Fourth, MetadataExt
is actually a bit of a red herring. The actual problem here is that rustdoc
is built as a kind of post-process of the compiler, inserted after type checking is done. This puts it after macro expansion. This is relevant because it's during macro expansion that platform-specific #[cfg(...)]
attributes are resolved. This is important because this is how the language does platform-specific code.
As a result, docs are only built for the platform you're specifically targeting. The docs on the official website all target Linux. As a result, nothing Windows-specific shows up. Now, if you download the Windows compiler, it comes with a set of docs, and those docs target Windows. If you open those up and search, you'll find std::os::windows::fs::MetadataExt
, which looks like this:
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;
}
(I can't just link to this for hopefully obvious reasons.)
As an aside, what you linked to isn't an RFC; it's an issue on the RFC repository. It's for tracking things that RFCs should be written about.
So, to wrap this all up: you can use the aforementioned crate or you can write platform-specific code, which will likely boil down to one path for Windows, and one path for everything else, using the two different MetadataExt
traits. One thing to be careful of is that the two systems use different epochs, meaning the times aren't directly comparable. UNIX uses an epoch of Jan 1 1970, Windows uses Jan 1 1601.
The simplest thing is probably to just use the crate mentioned above.
Upvotes: 12