Every time I upgraded an HDD or otherwise needed to move directory trees between disks, I faced an annoying MS Windows “feature”: timestamps get updated to current time on the copies of directories.
The annoyance is in the inconsistency with how plain files are copied in Windows: file timestamps, unlike directory timestamps, are always preserved.
It is in great contrast to UNIX, where to preserve timestamps of any files – plain, directory, sockets, devices – you just say so with the conventional flag of
-p, like in
cp -p or
In Windows, every single tool I tried – copy, xcopy, robocopy (all by Microsoft) – only copies timestamps for files, not for directories, yet I always felt like missing the info. A sort of nostalgia.
In the search I came across xxcopy, a gimmick to xcopy. Works beautifully in regards to almost everything, except… Unicode. Not only it doesn’t copy timestamps for directories (and files) with multibyte names, it doesn’t copy the files in the first place! That was unacceptable, so I had to go on investigate other options. Like archivers.
Well, zip (which is built into Windows XP) appears to hold all the original timestamps correctly for files as well as for folders. However, it seems impossible to extract folders with the timestamps set to their original values.
Another archiver – WinRAR – is totally OK with extracting correct folder timestamps. It is free to use for like 40 days, so it may be a viable solution at least with smaller directory trees.
For bigger trees, e.g. for cloning an entire hard disk, the temporary archive file space requirements may be too high. Here pipes come to mind.
WinRAR package has a command line version of the GUI archiver –
rar.exe. What’s even better, it’s got an extensive list of switches (reproducible with
rar -?). However, only reading from a pipe (
-si) is supported. And who on earth would need the ability to read without the complementary ability to write? Where do I get an archiver capable to write rar format to stdout so that rar.exe will have some material to work with? This looked stupid from the very beginning, so I didn’t give much effort investigating anonymous and named pipes operation in Windows. I finally decided to stop playing around, so I went on making my own tool.
The two tools I came up with are both based on traditional UNIX technologies:
- bash+find+touch from A collection of tools which provide Linux look and feel for Windows
- utime system call emulated by Perl for Windows
Both assume preparatory duplication of a tree with standard means. I suggest Robocopy for that as the most accurate copying utility in Windows. Besides it is written by Microsoft itself (it is a part of Microsoft Windows Resource Kit Tools and is available for free download).
Next goes the fixing stage of the job.
The first one mentioned is obvious: once you’re in UNIX environment, everything is possible.
The Perl method is probably more interesting for more users, as Perl installation may prove useful in a variety of Windows-native projects, like websites under IIS.
A simple Perl script traversing Windows filesystem (either NTFS or FAT32) makes use of utime() (sets “Last-access-date-time” and “Last-modified-date-time”) or optionally SetFileTime() (sets “Last-access-date-time”, “Last-modified-date-time” and “Created-date-time”) to fix timestamps for the directory tree copy.
As this post appeared in the first page on a Google search about Robocopy and WinRAR, I feel the need to add that Robocopy (since version 26, which I read came with Windows Vista) can perfectly copy directories with all timestamps. It can even correct the timestamps without having to re-copy the actual files, which was a “life-saver” for me once, when some program added one file to every single subdirectory of my main hard drive, thus changing their modified date to the current date, which was definitely an issue as I use folders’ timestamps a lot for sorting purposes — fortunately I had a backup and Robocopy solved this little nightmare in just a few seconds.
The switch to copy directory timestamps is :
(There’s also /TIMFIX which is described in the integrated /? help as “Fix file TIMes on all files, even skipped ones.)