我有另一种方法调用此函数3次以写入3个不同的文件。前两个文件将按预期复制到目标文件夹,第三个文件始终为零字节。如果我关闭删除,则可以看到所有3个临时文件均已成功写入。该代码未报告任何错误,但是在过程结束时,第三个文件始终为空。
有人知道为什么失败三分之一吗?
def write_file(file_destination: str, content: bytes):
with tempfile.NamedTemporaryFile() as fp:
fp.write(content)
shutil.copy(fp.name, file_destination)
以下变体有效,但是,我想了解为什么上面的代码中前两个文件起作用而第三个文件不起作用。
def write_file(file_destination: str, content: bytes):
with tempfile.NamedTemporaryFile(delete=False) as fp:
fp.write(content)
shutil.copy(fp.name, file_destination)
os.remove(fp.name)
答案 0 :(得分:2)
这是因为执行复制时尚未将content
写入磁盘。发生这种情况是因为写入是被缓冲的,并非总是在调用file.write
之后立即发生。
为了确保将内容在给定点写入磁盘,可以使用file.flush
。
对于您而言,将代码更改为:
def write_file(file_destination: str, content: bytes):
with tempfile.NamedTemporaryFile() as fp:
fp.write(content)
fp.flush()
shutil.copy(fp.name, file_destination)
有关何时将内容实际写入磁盘的更多信息,请参见io.BufferedWriter
的文档。相关部分是:
该缓冲区将被写到底层RawIOBase对象 在各种条件下,包括:
- 当缓冲区对于所有未决数据而言太小时;
- 调用flush()时;
- 当请求seek()时(对于BufferedRandom对象);
- 关闭或销毁BufferedWriter对象时。
因此,在您的第一个示例中,它可能仅在某些情况下有效,因为那些时候您正在写的内容超出了缓冲区,因此需要立即写出。
相反,您的第二个示例有效,因为当您退出with
块时,文件已关闭,因此需要清空缓冲区并将其写入磁盘。