Re: getting file creation date from NTFS
Re: getting file creation date from NTFS
- Subject: Re: getting file creation date from NTFS
- From: Alastair Houghton <email@hidden>
- Date: Sun, 23 May 2010 20:11:47 +0100
On 23 May 2010, at 19:07, Paul Sanders wrote:
> > At the BSD layer, getattrlist() is the way to go here, with the ATTR_CMN_CRTIME attribute.
>
> From http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/getattrlist.2.html:
>
> "Not all volumes support getattrlist(). The best way to test whether a volume supports this function is to simply call it and check the error result. getattrlist() will return ENOTSUP if it is not supported
> on a particular volume."
>
> I would hazard a guess that NTFS volumes don't support this.
And you'd be wrong. (BTW, why "hazard a guess" rather than either (a) testing this, or (b) looking at the kernel sources to find out? Testing it isn't hard, and looking is even easier once you know where to look...)
Back in 10.3, when it first appeared, NTFS supported getattrlist() but badly (only for volume capabilities), but as of 10.4 the implementation of getattrlist() in the kernel was changed to share a code path with stat() and it should work fine since then. stat64(), FWIW, only works as of 10.5.
> It's also a complicated API just to get a file time!
The man page is large, to be sure, but it's pretty easy to use. Something like (written in Mail):
struct {
uint32_t length;
struct timespec creationTime;
} attrBuf;
attrlist_t attrList;
memset (&attrList, 0, sizeof (attrList));
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
attrList.commonattr = ATTR_CMN_CRTIME;
if (getattrlist ("/Volumes/My NTFS Volume/My File", &attrList, &attrBuf,
sizeof (attrBuf), 0) < 0) {
// We failed, error code is in errno
if (errno == ENOTSUP) {
// Can't get the creation time without using stat64(), which is deprecated;
// won't happen for NTFS, but might for UFS or
} else {
// Report error to user
}
} else {
// Success
}
should retrieve *just* the creation time.
Obviously it's most efficient if you retrieve *everything* you want in one hit, rather than calling this separately for the creation time. In practice, you can replace your use of stat with getattrlist(), which may even be a performance win because some attributes that stat() returns can be expensive to compute.
It's also worth pointing out that stat64() will synthesise a creation time from the last changed time if it isn't able to get one. getattrlist() should fail with EINVAL in that case instead, which at least means you can tell whether the filesystem is providing that data or not.
> The more I see of this, the more I think that the Carbon File Manager is the best option. I plan to review my own code in the light of this thread. I'm not sure whether stat returns local times or UTC (it returns local times on Windows). I am often on UTC here so it's not always possible to tell. But, luckily, it is summer :)
Windows is being dumb (Windows actually bases everything off local time, which creates the obvious problem of the operating system having to keep track of whether it's adjusted for daylight savings yet or not; if you have two copies of Windows installed, it's quite likely that every daylight savings boundary will move your system clock by two hours rather than the usual one...).
On sensible platforms, stat() returns UTC, as you'd expect.
Anyway, we're getting a bit off topic here. There's nothing wrong with using the Carbon API, *or* the BSD API for this (guess what Carbon does under the covers...)
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden