在python中以全微秒精度设置文件的mtime

假设我创建一个测试文件并检查其mtime:

$touch testfile.txt 
$stat testfile.txt
  File: `testfile.txt'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d    Inode: 3413533     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ me)   Gid: ( 1000/ me)
Access: 2014-09-17 18:38:34.248965866 -0400
Modify: 2014-09-17 18:38:34.248965866 -0400
Change: 2014-09-17 18:38:34.248965866 -0400
 Birth: -

$date -d '2014-09-17 18:38:34.248965866 -0400' +%s
1410993514

上面的mtime以微秒精度列出(我意识到系统时钟分辨率使该分辨率的较高部分无效). utimes(2)系统调用使我可以传递微秒.但是,os.utime()函数似乎将其组合为一个数字.

我可以像这样通过一个浮点数:

>>> os.utime('testfile.txt', (1410993514.248965866, 1410993514.248965866))

但现在

$stat testfile.txt 
  File: `testfile.txt'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d    Inode: 3413533     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ me)   Gid: ( 1000/ me)
Access: 2014-09-17 18:38:34.248965000 -0400
Modify: 2014-09-17 18:38:34.248965000 -0400
Change: 2014-09-17 18:46:07.544974140 -0400
 Birth: -

可能会丢失精度,因为该值已转换为浮点数,而python知道比信任最后几个小数位还更好.

有没有办法通过python设置完整的微秒字段?

解决方法:

您已经设置了完整的微秒.微表示百万分之一; .248965是248965微秒. .248965866是248965866纳秒.

当然,它也是248965.866微秒,但是Python在每个平台上用来设置时间的可移植API,但Windows仅接受整数微秒,而不是分数. (事实上​​,POSIX不需要系统记住小于微秒的任何内容.)

从Python 3.3开始,os.utime在支持设置纳秒的方法的系统上添加了ns关键字参数.1,2因此,您可以传递整数倍的时间,然后在单独的参数中传递纳秒.像这样:

>>> os.utime('testfile.txt', (1410993514, 1410993514), ns=(248965866, 248965866))

最后一件事:

Presumably the precision is lost because the value was converted to a float and python knew better than to trust the last few decimal places.

这实际上可能是有道理的…但是Python没有做到这一点.您可以看到它使用here的确切代码,但基本上,它们对舍入所做的唯一补偿是确保负微秒变为0.3

但是您说对了,这里的舍入错误是一个潜在的问题……这就是为什么* nix和Python都通过使用单独的秒和纳秒整数来避免该问题的原因(Windows通过使用64位int而不是double来解决此问题).

1如果您使用的是Unix,则意味着您拥有一个utimens函数,该函数类似于utimes,但是使用struct timespec而不是struct timeval.您应该将其安装在任何非古老的linux / glibc系统上;在* BSD上,它取决于内核,但是我认为,如今除了OS X之外,其他所有东西都具有它;否则,您可能没有.但是,最简单的检查方法是手动操作.

2在Windows上,Python使用以100ns为单位的本机Win32 API,因此您只能通过这种方式获得一位数字,而不是两位数字.

3我链接到3.2,因为3.3较难理解,部分原因是您关心的ns支持,但主要是因为您不需要的at支持.

上一篇:Linux,C:access()无法捕获权限问题或其他问题


下一篇:STAT 3701 Homework