Python 脚本保证设法完成读取已删除的文件
Guarantee of Python script manages to finish reading deleted file
我是 运行 bash 中 Windows 的 Python 脚本,为了简化,
with open('large.txt', 'r') as infile:
for line in infile.readlines():
print(line)
它读取的文件预计会很大。在执行过程中,文件在 Windows 中被删除。在我尝试过的示例中,脚本确实完成了打印文件的全部内容。
例如,
的输出
with open('large.txt', 'w') as outfile:
for n in range(10000000):
outfile.write('{}\n'.format(n))
Q:我的具体问题是,如果我能保证这种行为,脚本将设法处理整个文件。例如,如果大小是这样的,即使它适合光盘,但它不适合内存。
Q:如果没有,脚本的这一部分是否会退出执行,但我可以捕捉到一些异常以产生替代行为?
当你谈论 Windows 或 WSL 时,答案是不同的,我相信。
在 Windows,实际删除一个文件 "marks the file for deletion",但真正的删除只有在所有句柄都关闭后才会发生。该文件仍在磁盘上,即使您查找它时它似乎并不存在。在原始文件被完全删除之前,您无法创建另一个同名文件。您可以继续阅读该文件,直到它被删除。
WSL 提供 POSIX 文件语义——使用 POSIX 语义,文件改为“未链接”并且在最后一个引用消失之前不会被删除。只要你有文件的引用就可以继续阅读,由于文件已经完全取消链接,你可以创建一个新的同名文件。
Q: My concrete question is if I have guarantees of this behavior, that the script will manage to process the entire file. For example, if the size is such that even though it fits in disc, it doesn't fit in memory.
回答您的问题:是的,脚本将完成对文件的处理。
文件仍在磁盘上,不在内存中。
在 Windows 和 WSL 上,直到所有引用都消失后,文件才真正被删除,但语义有点不同。
重要提示
你说文件很大,但是这段代码:
with open('large.txt', 'r') as infile:
for line in infile.readlines():
print(line)
它的作用是将整个文件读入内存,然后一次一行地打印出来。你可能想要这个:
with open('large.txt', 'r') as infile:
for line in infile:
print(line)
这将一次只读取一行+一些缓冲数据。如果您的文件很大,这将有所不同。
Dietrich 所说的是正确的:如果一个进程只是 "delete"s 文件而没有其他进程打开文件,那么,是的,你会读到文件的末尾(假设缺少IO 错误等)。但我认为指出一个不同但相关的问题可能会有用
如果另一个进程 truncates 该文件,或者在它被删除之前,或者该进程有一个打开的文件句柄并在删除后截断它,那么您的程序将在到达新的结尾时停止读取文件
我是 运行 bash 中 Windows 的 Python 脚本,为了简化,
with open('large.txt', 'r') as infile:
for line in infile.readlines():
print(line)
它读取的文件预计会很大。在执行过程中,文件在 Windows 中被删除。在我尝试过的示例中,脚本确实完成了打印文件的全部内容。
例如,
的输出with open('large.txt', 'w') as outfile:
for n in range(10000000):
outfile.write('{}\n'.format(n))
Q:我的具体问题是,如果我能保证这种行为,脚本将设法处理整个文件。例如,如果大小是这样的,即使它适合光盘,但它不适合内存。
Q:如果没有,脚本的这一部分是否会退出执行,但我可以捕捉到一些异常以产生替代行为?
当你谈论 Windows 或 WSL 时,答案是不同的,我相信。
在 Windows,实际删除一个文件 "marks the file for deletion",但真正的删除只有在所有句柄都关闭后才会发生。该文件仍在磁盘上,即使您查找它时它似乎并不存在。在原始文件被完全删除之前,您无法创建另一个同名文件。您可以继续阅读该文件,直到它被删除。
WSL 提供 POSIX 文件语义——使用 POSIX 语义,文件改为“未链接”并且在最后一个引用消失之前不会被删除。只要你有文件的引用就可以继续阅读,由于文件已经完全取消链接,你可以创建一个新的同名文件。
Q: My concrete question is if I have guarantees of this behavior, that the script will manage to process the entire file. For example, if the size is such that even though it fits in disc, it doesn't fit in memory.
回答您的问题:是的,脚本将完成对文件的处理。
文件仍在磁盘上,不在内存中。
在 Windows 和 WSL 上,直到所有引用都消失后,文件才真正被删除,但语义有点不同。
重要提示
你说文件很大,但是这段代码:
with open('large.txt', 'r') as infile:
for line in infile.readlines():
print(line)
它的作用是将整个文件读入内存,然后一次一行地打印出来。你可能想要这个:
with open('large.txt', 'r') as infile:
for line in infile:
print(line)
这将一次只读取一行+一些缓冲数据。如果您的文件很大,这将有所不同。
Dietrich 所说的是正确的:如果一个进程只是 "delete"s 文件而没有其他进程打开文件,那么,是的,你会读到文件的末尾(假设缺少IO 错误等)。但我认为指出一个不同但相关的问题可能会有用
如果另一个进程 truncates 该文件,或者在它被删除之前,或者该进程有一个打开的文件句柄并在删除后截断它,那么您的程序将在到达新的结尾时停止读取文件