【问题标题】:Is it safe to remove the containing directory after a file in it is opened?打开文件后删除包含目录是否安全?
【发布时间】:2020-05-09 12:12:12
【问题描述】:

我有一些代码需要返回一个文件对象并清理包含的目录,例如:

def create_file():
    # create a temp directory: temp_dir
    # generate a file inside the directory: filename

    file_obj = open(filename, 'rb')
    shutil.rmtree(temp_dir)
    return file_obj

如果我有文件句柄(open() 的结果),删除包含目录是否安全?

【问题讨论】:

  • 你要保证目录是空的;您不能删除非空目录。所以,如果你删除文件和保存它的目录,你会没事的(无论如何,在 POSIX 系统上——Windows 对你可以做什么有自己的看法)。如果shutil.rmtree 删除了整棵树,应该没问题。
  • 尝试谷歌搜索“删除文件打开文件句柄”。答案取决于操作系统。这是一个示例:stackoverflow.com/questions/2028874/…

标签: python python-3.x file directory delete-file


【解决方案1】:

取决于您如何定义“安全”。在 linux 机器上:

>>> p = os.path.join(os.getcwd(), "tmpdir")
>>> def foo(p):
...     os.makedirs(p)
...     f = open(os.path.join(p, "tmp.txt"), "w")
...     shutil.rmtree(p)
...     return f
... 
>>> f = foo(p)
>>> f
<open file '/home/bruno/tmpdir/tmp.txt', mode 'w' at 0x7f14f65c2270>
>>> f.write("foo")
>>> f.close()
>>> f.name
'/home/bruno/tmpdir/tmp.txt'
>>> open(f.name).read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '/home/bruno/tmpdir/tmp.txt'
>>> 
>>> os.listdir(p)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/home/bruno/tmpdir'

编辑

所以如果我要写入文件,我不能删除包含目录,是吗?

嗯,显然不是。无论如何,这没有任何意义,因为,正如你问自己的那样:

在这种情况下 write() 写在哪里?

这是个好问题……

“文件”和“目录”只是操作系统给出的表示。从技术上讲,操作系统将文件数据写入它想要的位置(并且它可以分散在不同位置的多个块中),并将元数据写入已知位置,告诉哪些块属于哪个“文件”以及哪个“文件”属于哪个“目录”。

此外,除非您另有说明,否则 IO 会被缓冲,因此 write() 不一定会立即写入任何内容。话虽如此,使用无缓冲文件(和/或在write 之后刷新文件)不会改变上述 sn-p 的行为(至少不会在带有 python 2.7 的 ubuntu-linux 上)。

但无论如何:打开文件以写入目录,然后在文件被使用之前删除整个目录的整个想法让我觉得有点可疑(这是轻描淡写的 xD)——操作系统应该拒绝删除目录,因为其中有一个文件,或者它应该删除文件以及目录,然后写入一个无论如何都无法读取的文件有什么意义?

现在这看起来真的像一个 XY 问题,所以也许解释(在某些情况下)为什么你“需要”这样一个奇怪的东西可能会有所帮助。另外,请注意 Python 已经有 some support for temporary files and directories

【讨论】:

  • 所以如果我要写入文件,我不能删除包含目录,是吗?顺便说一句,write() 在这种情况下写在哪里?
  • 我需要这个文件来阅读。但是,我认为,如果我们然后倒回文件,也可以使用写入。
  • @planetp 恐怕我没有说清楚。当我写“解释(在某些情况下)”时,我要问的是“你要解决的真正问题是什么”(参见xyproblem.info
猜你喜欢
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
相关资源
最近更新 更多