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

问题描述 投票:0回答:2

假设我创建一个测试文件并检查其 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设置完整的微秒字段?

python linux stat
2个回答
3
投票

您已经正在设置完整的微秒。微的意思是百万分之一;

.248965
是 248965 微秒。
.248965866
是 248965866 nano 秒。

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

从 Python 3.3 开始,

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

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

最后一件事:

大概精度会丢失,因为该值被转换为浮点数,而 python 知道最好不要相信最后几个小数位。

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

但是你说得对,舍入错误是这里的一个潜在问题……这就是为什么 *nix 和 Python 通过使用单独的

seconds
nanoseconds
整数来避免这个问题(Windows 通过使用 64 位 int 来解决这个问题)双)。


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
支持。


0
投票

os.utime()
接受
atime
mtime
的元组。 可以使用参数
int
times=
以秒或纳秒(作为
ns=
)为单位指定。

这是如何使用纳秒精度的

os.utime

time_nanoseconds = int(1410993514.248965866 * 1e9)
os.utime('testfile.txt', ns=(time_nanoseconds, time_nanoseconds))
© www.soinside.com 2019 - 2024. All rights reserved.