Python打开了一个文件并正在读取它的数据,为啥即使我删除了这个文件,python仍然可以读取它的数据?
Posted
技术标签:
【中文标题】Python打开了一个文件并正在读取它的数据,为啥即使我删除了这个文件,python仍然可以读取它的数据?【英文标题】:Python opened one file and is reading its data, why python still can read its data even I delete this file?Python打开了一个文件并正在读取它的数据,为什么即使我删除了这个文件,python仍然可以读取它的数据? 【发布时间】:2015-12-01 07:46:45 【问题描述】:我的 python 程序是从 txt 文件中读取数据并将数据插入到我的 postgre 数据库中。该程序已经启动并继续运行。然后我不小心删除了磁盘上的文件,但程序仍然在继续运行并向数据库中插入数据。
是不是因为python打开一个文件时,它会将文件加载到内存中,所以即使我删除磁盘上的文件,也不影响正在运行的程序?但是我的文件超过3GB,python真的把我的文件加载到内存中了吗?我担心我在数据库中的数据是否正确。
这是我打开文件的代码:
f = open("/home/minjian/Documents/tweets2009-07.txt")
我的操作系统是:
Linux minjian-OptiPlex-9020 3.16.0-46-generic #62~14.04.1-Ubuntu SMP Tue Aug 11 16:27:16 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
【问题讨论】:
我认为这个问题更多是关于文件系统等的,所以最好在 SU 上提问。但既然他是在编程的时候来到这里的…… 【参考方案1】:符合 POSIX 的操作系统将实际文件 数据 保留在磁盘上,直到所有文件句柄都关闭,即使不再有任何链接指向数据。
【讨论】:
【参考方案2】:大多数文件系统不会删除文件内容,而只会删除对文件的引用。当新文件请求旧文件的空间或可用空间被工具明确覆盖时,内容将被删除。
让我用 NTFS 解释一下。文件首先是 MFT(主文件表)中的一个条目。它就像一个索引,说有一个名为“xyz”的文件,可以在地址 0x87-0x95 找到。删除文件时,索引条目被删除,但地址 0x87-0x95 处的内容不会。您的程序从打开文件时就知道这些地址,因此它仍然可以读取它们,即使索引条目不再存在。
【讨论】:
【参考方案3】:文件的路径不是文件,删除该路径不会“删除磁盘上的文件”。访问文件的路径只是文件的链接。当 python 通过该链接打开文件时,它可以访问该文件,并且随后删除该链接(例如,rm foo
)不会改变 python 对该文件的访问。在删除所有引用之前,文件系统不会删除文件,包括正在运行的进程持有的引用。
文件没有加载到内存中。它仍然在磁盘上。
【讨论】:
某些文件系统即使删除所有引用也不会删除文件内容。 确实,大多数人不会删除数据。随着时间的推移和磁盘的使用,它只会被覆盖。这是一个常见的安全问题。 当 Python 读取/写入文件时,文件系统不会删除文件,因此当 Python 有权访问它时。当 Python 关闭对文件的访问时,文件系统可以删除文件。 Python 在加载文件内容并将值分配给对象引用时会将文件内容加载到内存中。【参考方案4】:除非你告诉它,否则 Python 不会将文件加载到内存中。
当你的 python 程序打开文件时,它会创建一个指向它的链接,这个链接是 linux/unix 中文件处理的关键。
当您列出目录并查看文件时,您会看到该目录与该文件的链接。删除文件时,实际上是在删除链接。操作系统然后注意到该文件没有更多链接,因此将其删除。在这种情况下,当您删除文件时,python 程序仍然有一个链接,因此该文件仍在磁盘上,但您在其目录中看不到它,因为该链接已消失。当你的 python 程序关闭文件句柄或退出时,在后台,python 会要求操作系统删除它对文件的链接,并且操作系统会注意到这是最后一个链接并且文件已经消失了。
您可以使用 ln 命令创建链接,以便文件出现在两个目录中。 ls -l的话,权限后面左边的数字就是硬链接的个数。
【讨论】:
在 python 中列出目录不会生成指向文件的链接。打开文件确实会创建一个文件句柄。但是文件句柄不会阻止任何人删除文件。删除只会删除 inode 表中的条目,而不是磁盘上的内容。以上是关于Python打开了一个文件并正在读取它的数据,为啥即使我删除了这个文件,python仍然可以读取它的数据?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我无法打开/读取从 Python 调用的 C 扩展名中的 txt 文件?