Python shutil copy命令写入0字节文件以复制临时文件

Python shutil copy命令写入0字节文件以复制临时文件,python,shutil,temp,Python,Shutil,Temp,我有另一个方法调用这个函数三次来编写三个不同的文件。前两个文件按预期复制到目标文件夹,第三个文件始终为零字节。如果我关闭删除,我可以看到所有3个临时文件都已成功写入。代码不报告任何错误,但在进程结束时,第三个文件始终为空 有人知道为什么三次中有一次失败吗 def write_file(file_destination: str, content: bytes): with tempfile.NamedTemporaryFile() as fp: fp.write(cont

我有另一个方法调用这个函数三次来编写三个不同的文件。前两个文件按预期复制到目标文件夹,第三个文件始终为零字节。如果我关闭删除,我可以看到所有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)

这是因为执行复制时,
内容
尚未写入磁盘。这是因为写操作是缓冲的,并且并不总是在调用
file.write之后立即发生。
要确保在给定点将内容写入磁盘,可以使用
file.flush

在您的情况下,只需将代码更改为:

def write_文件(文件目的地:str,内容:字节):
使用tempfile.NamedTemporaryFile()作为fp:
fp.write(内容)
fp.flush()
shutil.copy(fp.name,文件\目标)
有关内容何时实际写入磁盘的详细信息,请参阅的文档。有关部分是:

缓冲区将被写入底层RawIOBase对象 在各种条件下,包括:

  • 当缓冲区对于所有挂起的数据来说太小时
  • 调用flush()时
  • 请求seek()时(对于BufferedRandom对象)
  • 当BufferedWriter对象关闭或销毁时
因此,在第一个示例中,它可能只在某些时候起作用,因为您正在编写的内容超出了缓冲区,因此需要立即写出


相反,您的第二个示例是有效的,因为当您使用
块退出
时,文件将关闭,因此需要刷新缓冲区并将其写入磁盘。

请注意,在调用file对象的
flush()
后,建议使用
os.fsync(fd)
flush
清除Python的文件对象缓冲区,
fsync
指示操作系统将文件描述符对应的文件系统缓冲区写入磁盘。多亏了,这是有意义的,前两个文件较大,所以第三个文件较小可能意味着它没有跨越flush边界。。。