python os.path.getmtime() 时间不变

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

我对 python 的

os.path.getmtime()
函数有一个快速问题。我观察到一些奇怪的行为。我正在开发一个网络应用程序,它会定期检查某个文件是否已被修改,并根据该文件决定是否刷新。

在我的本地 python 命令行中,当我更改文件并调用

os.path.getmtime(file_name)
时,
mtime
的返回值已更改以反映文件中的更改。

但是,当我在网络应用程序中调用

os.path.getmtime()
时,更改前后的返回值是相同的。我在网上做了一些研究,发现一些东西表明需要重新加载操作系统模块才能注册文件的更改。因此,在我的网络应用程序中,我重新加载了
os
模块,但
mtime
仍然没有反映对文件的更改。有其他人以前遇到过这个问题或知道解决方案吗?我在下面包含了来自网络应用程序的代码片段:

import os

def function_name():
    reload(os)
    file_path = '/dir/lib/some_file.js'

    try:
        mtime = os.path.getmtime(file_path)
    except os.error:
        pass

    return mtime
python python-2.7 os.path
4个回答
3
投票

我今天遇到了这个问题并发现了这个问题,所以我想我应该在这里记录一下。我的案例是单元测试,因此它可能略有不同,因为它涉及的时间尺度比手动测试更小。

修改时间受您的文件系统的限制。如果检查修改时间,然后写入少量数据,然后再次检查修改时间,两个时间戳可能完全相等。如果第一次时间戳检查和写入结束之间的时间小于时间分辨率,它们将相等。

各种常见文件系统时间分辨率的一些统计:

  • FAT32:2秒
  • ext3:1秒
  • exFAT:10ms
  • NTFS:100ns
  • ext4:1ns

您可以期望嵌入式系统使用 FAT,并且时间分辨率为 2 秒。较旧的 Windows 系统将在 2 秒范围内。较新的 Windows 系统将有 100ns 或 10ms。较旧的 UNIX 系统通常有 1。较新的 UNIX 系统的分辨率为 1ns。

如果

<time for time stamp check> + <time for file write>
小于时间分辨率,文件可能会显示为未修改。

我看到了这些可能的解决方案:

  • 在您正在编写的文件的标题中包含更准确的修改时间。文件编写器甚至可以在写入之前检查文件是否已经存在,并将纳秒修改时间至少增加 1 以保证其更新(以时间戳准确性为代价)。
  • 在其他地方存储每个文件的编辑频率。使用此数字可查看自您上次检查以来是否已对其进行过编辑。请注意,原子地写入文件并同时更新修改计数可能是不可能的。
  • 也许可以通过睡眠设计一些技巧,使得第一次时间戳检查和文件写入之间的时间始终至少是最小时间分辨率。这在很大程度上取决于您的设置类型,并且它会阻塞线程。

1
投票

我没有足够的声誉来添加此评论...

不清楚你是如何测试的,你的网络应用程序的一个页面是否测试

  • 打印时间
  • 更新文件
  • 打印时间

或者

  • 简单地打印 mtime

如果您的网络应用程序测试过程是

  • 请求测试mtime页面
  • 手动更新文件
  • 请求测试mtime页面
  • 请注意,两个页面视图上的 mtime 是相同的

我的第一个猜测是 Web 客户端、代理或服务器缓存。


0
投票

也许您可以尝试获取除 mtime 之外的文件的一般统计信息,例如大小。

服务器上更改前后(即在终端窗口中查看 ls -l 时)文件的预期大小/运行时间是否相同或不同。

如果使用此类命令行工具时的统计数据相同,则可能是文件没有在您认为的位置进行编辑。

如果大小/运行时间不同,也许使用

os.stat(filename)

看看它是否给出了正确的值。


0
投票

对我来说(Linux,内核 6.6.11-200.fc39.x86_64,btrfs 文件系统),我想检测文件是否已更改,因为我在写入之前读取了它 - 所有这些都在单元测试中,所以我将文件创建为嗯:

f = "data.txt"
with open(f, "w") as fd:
    fd.write("aaa")   # this is to simulate file creation, we are not actually loading it here
before = os.path.getmtime(f)
with open(f, "w") as fd:
    fd.write("bbb")   # this is to simulate file changing
after = os.path.getmtime(f)
print(f"File not changed: {before == after}   ({after - before})")

看起来这些写入操作彼此距离太近,或者

mtime
时间戳没有足够大的精度 - 当我在循环中运行它时,看看上面代码的输出:

f = 'data.txt'
for i in range(10):
    with open(f, "w") as fd:
        fd.write("aaa")   # this is to simulate file creation, we are not actually loading it here
    before = os.path.getmtime(f)
    with open(f, "w") as fd:
        fd.write("bbb")   # this is to simulate file changing
    after = os.path.getmtime(f)
    print(f"File not changed: {before == after}   ({after - before})")

输出(大部分都是零,必须重新运行几次):

File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: False   (0.0010001659393310547)
File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: True   (0.0)
File not changed: True   (0.0)

所以我使用的解决方法是在这两次写入之间添加 0.001 秒的延迟:

f = 'data.txt'
for i in range(10):
    with open(f, "w") as fd:
        fd.write("aaa")
    before = os.path.getmtime(f)
    time.sleep(0.001)
    with open(f, "w") as fd:
        fd.write("bbb")   # this is to simulate file changing
    after = os.path.getmtime(f)
    print(f"File not changed: {before == after}   ({after - before})")

现在输出:

File not changed: False   (0.0010001659393310547)
File not changed: False   (0.0009999275207519531)
File not changed: False   (0.002000093460083008)
File not changed: False   (0.0009999275207519531)
File not changed: False   (0.0009999275207519531)
File not changed: False   (0.0010001659393310547)
File not changed: False   (0.0009999275207519531)
File not changed: False   (0.0009999275207519531)
File not changed: False   (0.0010001659393310547)
File not changed: False   (0.0009999275207519531)
© www.soinside.com 2019 - 2024. All rights reserved.