为什么直到我停止程序才写入文件?
- 2025-03-06 08:54:00
- admin 原创
- 77
问题描述:
我正在运行测试,发现直到我按下 Control-C 中止程序时,文件才真正写入。有人能解释为什么会发生这种情况吗?
我希望它能同时写入,这样我就可以在进程中间读取该文件。
import os
from time import sleep
f = open("log.txt", "a+")
i = 0
while True:
f.write(str(i))
f.write("
")
i += 1
sleep(0.1)
解决方案 1:
写入磁盘很慢,因此许多程序将写入存储为大块,然后一次性写入。这称为缓冲,当您打开文件时,Python 会自动执行此操作。
当你写入文件时,你实际上是在写入内存中的“缓冲区”。当缓冲区填满时,Python 会自动将其写入磁盘。你可以告诉它“现在将缓冲区中的所有内容写入磁盘”,方法是
f.flush()
这并不是全部,因为操作系统可能也会缓冲写入。你可以告诉它使用以下命令写入文件缓冲区
os.fsync(f.fileno())
最后,你可以用 告诉 Python 不要缓冲某个文件,open(f, "w", 0)
或者只保留一行缓冲区open(f,"w", 1)
。当然,这会减慢该文件上的所有操作,因为写入速度很慢。
解决方案 2:
您需要f.close()
将文件写入缓冲区刷新到文件。或者,在您的情况下,您可能只想执行此操作,f.flush(); os.fsync();
以便继续使用打开的文件句柄进行循环。
别忘了import os
。
解决方案 3:
您必须强制写入,因此我使用以下几行来确保文件已写入:
# Two commands together force the OS to store the file buffer to disc
f.flush()
os.fsync(f.fileno())
解决方案 4:
您将需要检查file.flush()
- 但请注意,这可能不会将数据写入磁盘,引用:
注意:flush() 不一定会将文件的数据写入磁盘。使用 flush() 后跟 os.fsync() 可确保此行为。
关闭文件(file.close()
)也将确保数据被写入 - 使用with
将隐式地执行此操作,并且通常是提高可读性和清晰度的更好选择 - 更不用说解决其他潜在问题。
解决方案 5:
这是 windows 主义。如果你.close()
在处理完文件后添加一个显式命令,那么它就会出现在资源管理器中。即使只是刷新它也可能足够了(我手边没有 windows 框可以测试)。但基本上 f.write实际上并没有写入,它只是附加到写入缓冲区 - 直到缓冲区被刷新,你才会看到它。
在 UNIX 上,在这种情况下,文件通常会显示为 0 字节文件。
解决方案 6:
要刷新的文件处理程序。
f.flush()
解决方案 7:
文件不会被写入,因为输出缓冲区直到垃圾收集生效时才会被刷新,并且会刷新 I/O 缓冲区(很可能通过调用f.close()
)。
或者,在循环中,您可以调用f.flush()
后跟os.fsync()
,如此处所述。
f.flush()
os.fsync()
话虽如此,如果您计划与代码的其他部分共享该文件中的数据,我强烈建议使用StringIO
对象。
解决方案 8:
写入文件的数据正在被缓冲,只有当缓冲区满或者文件关闭时,缓冲的数据才会写入文件。
如果您以文本模式打开文件,并且希望每次写完一行时都刷新输出,则在打开文件时将缓冲设置为行缓冲:
f = open("log.txt", "a+", buffering=1)
有关更多详细信息,请参阅https://docs.python.org/3/library/functions.html#open。
如果你想要确保文件与程序中某个特定点迄今为止写入的内容保持同步,并且不介意在这些点之间缓冲输出,那么你可以在这些点明确刷新缓冲区,方法是
f.flush()
如果您想要刷新部分行,则使用行缓冲时刷新也很有用。
扫码咨询,免费领取项目管理大礼包!