Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File modification times not equal after calling shutil.copystat(file1, file2) under Windows

I run the following code with Python 2.7.5. under Windows:

import os, shutil, stat, time

with open('test.txt', 'w') as f: pass # create an arbitrary file
shutil.copy('test.txt', 'test2.txt') # copy it
shutil.copystat('test.txt', 'test2.txt') # copy its stats, too

t1 = os.lstat('test.txt').st_mtime # get the time of last modification for both files
t2 = os.lstat('test2.txt').st_mtime

print t1 # prints something like: 1371123658.54
print t2 # prints the same string, as expected: 1371123658.54
print t1 == t2 # prints False! Why?!

I expect both timestamps (=floats) to be equal (as their string representations suggest), so why does t1 == t2 evaluate to False?

Also, I was unable to reproduce this behaviour with less code, i.e. without comparing the timestamps retrieved via os.lstat from two different files. I have the feeling, I am missing something trivial here...


Edit: After further testing I noticed, that it does print True once in a while, but not more often than once every 10 runs.


Edit 2: As suggested by larsmans:
print ("%.7f" % t1) # prints e.g. 1371126279.1365688
print ("%.7f" % t2) # prints e.g. 1371126279.1365681

This raises two new questions:

  1. Why are the timestamps not equal after calling shutil.copystat?
  2. print rounds floats by default?!
like image 764
Alexander Tobias Bockstaller Avatar asked Jun 13 '13 11:06

Alexander Tobias Bockstaller


People also ask

Does Shutil work on Windows?

It means you should know the target OS (Windows/Linux/Mac OS X etc.) wherever you'll run the program. With the shutil module, you can automate copying both the files and folders. This module follows an optimized design.

What is the difference between Shutil copy () and Shutil Copystat () functions?

copystat() method in Python is used to copy the permission bits, last access time, last modification time, and flags value from the given source path to given destination path. The shutil. copystat() method does not affect the file content and owner and group information.

What is the difference between Shutil copy and Shutil copy 2?

The shutil.copy2() method is identical to shutil.copy() except that copy2() attempts to preserve file metadata as well.


1 Answers

The problem is with conversion between different formats during the copystat call. This is because Windows stores file times in a fixed-point decimal format, while Python stores them in a floating-point binary format. So each time there is a conversion between the two formats, some accuracy is lost. During the copystat call:

  1. A call to os.stat converts the Windows format to Python's floating-point format. Some accuracy is lost.
  2. os.utime is called to update the file time. this converts it back to the Windows format. Some accuracy is lost again, and the file time is not necessarily the same as the first file's.

When you call os.lstat yourself, a third inaccurate conversion is performed. Due to these conversions, the file times are not exactly the same.

The documentation for os.utime mentions this:

Note that the exact times you set here may not be returned by a subsequent stat() call, depending on the resolution with which your operating system records access and modification times


Regarding your second question (why print appears to show the same values for both): Converting a floating-point value to a string with str(f) or print f will round the value. To get a value guaranteed to be unique for different floating-point values, use print repr(f) instead.

like image 79
interjay Avatar answered Sep 19 '22 04:09

interjay