在python中设置具有完整微秒精度的文件的mtime

时间:2014-09-17 22:49:23

标签: python linux stat

假设我创建了一个测试文件并检查其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()函数似乎将它组合成一个数字。

我可以像这样传递float

>>> 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: -

大概是精度丢失了,因为值被转换为float并且python知道比信任最后几个小数位更好。

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

1 个答案:

答案 0 :(得分:4)

您已经 设置完整的微秒。微意味着百万分之一; .248965是248965微秒。 .248965866是248965866 nano 秒。

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

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

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

最后一件事:

  

大概是精度丢失了,因为值被转换为float并且python知道比信任最后几个小数位更好。

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

但你是对的,舍入错误在这里是一个潜在的问题...这就是为什么* nix和Python都通过使用单独的secondsnanoseconds整数来避免这个问题(并且Windows通过使用它来解决它一个64位的int而不是一个double。)


1如果您使用的是Unix,则表示您的utimens功能类似于utimes,但需要struct timespec而不是struct timeval。你应该在任何非古老的linux / glibc系统上拥有它;在* BSD上它取决于内核,但我认为除了OS X之外的所有内容现在都有它;否则你可能没有它。但最简单的检查方法是man utimens

2在Windows上,Python使用以100ns为单位处理的本机Win32 API,因此这种方式只能获得一个额外数字,而不是三个。

3我链接到3.2,因为3.3有点难以理解,部分原因是你关心的ns支持,但主要是因为你提供的at支持“T