为什么检查然后立即打开文件风险?

时间:2018-01-03 11:45:39

标签: python file

在这个问题中阅读答案:How do I check whether a file exists using Python?,答案说明了这一点:

  

如果您要检查的原因是if file_exists: open_it(),那么在try周围使用$post会更安全   打开它。检查然后打开要删除的文件或   当您检查时和尝试打开它时,它们之间会移动。

     

如果您不打算立即打开文件,则可以使用   os.path.isfile

我无法理解为什么检查(通过os.path)然后打开被移动或删除的文件的风险。

这究竟是什么意思?

2 个答案:

答案 0 :(得分:5)

你误解了答案所说的内容。它并未表示使用os.path然后打开风险删除。

它实际上说检查文件是否存在,然后用两个单独的步骤打开它并不能保证文件在打开时仍然存在

这里的原则是操作的原子性。这是一个单一的操作 -

try:
    with open(filename) as f:
        ... # do something     
except OSError:
    ... # do something else

尝试一个原子操作中打开文件。如果找不到该文件,将捕获并处理错误。

然而!这段代码 -

if os.path.isfile(filename):
    with open(filename) as f:
        ... # do something 

有两件事 -

  1. 检查文件是否存在
  2. 打开文件
  3. 这些是两个非原子操作,并且没有任何保证在第一步和第二步之间无法删除/删除文件。就代码安全而言,这使得这个选项不那么安全。

    您应该使用什么取决于您的使用案例。如答案所述,如果您不打算立即打开文件,只需使用os.path.isfile即可。

答案 1 :(得分:2)

没有人可以保证,在您检查文件存在之后以及实际打开之前文件会发生什么。例如,它可以被删除,重命名或移动。

因此,支票不会为您提供任何其他有用的信息。您知道该文件存在于某个时间点,但您仍需要使用try / except封装文件open语句以确保不会出现这种可能性。

当你这样做时,你实际上并不需要存在检查信息,因为你的异常处理无论如何都会为你做这件事。

如果您完全控制环境并且绝对可以保证其他进程或用户不会篡改该文件,那么您可以放心检查并打开。在我看来,编程仍然是不好的,因为你为系统设置了一个约束,没有其他人可以触摸这个文件"没有以任何方式实际执行它,您可能会在以后遇到问题。