繁体   English   中英

在python中将一个文件的内容复制到另一个文件

[英]copying one file's contents to another in python

我被教导在 python 中读取文件的最佳方法是执行以下操作:

with open('file.txt', 'r') as f1:
    for line in f1:
        do_something()

但我一直在想。 如果我的目标是将一个文件的内容完全复制到另一个文件,这样做是否有任何危险:

with open('file2.txt', 'w+') as output, open('file.txt', 'r') as input:
    output.write(input.read())

这有可能以我不期望的方式表现吗?

同样,如果文件是二进制文件而不是文本文件,我将如何处理该问题。 在这种情况下,将没有换行符,因此readline()for line in file将不起作用(对吗?)。

编辑是的,我知道shutil 如果这正是我想要做的,有很多更好的方法来复制文件。 我想特别了解这种方法的潜在风险(如果有的话),因为我可能需要做更高级的事情,而不仅仅是将一个文件复制到另一个文件(例如将多个文件复制到一个文件中)。

请注意, shutil模块还包含copyfileobj() ,基本上像 Barmar 的回答一样实现。

或者,回答您的问题:

from shutil import copyfileobj

with open('file2.txt', 'wb') as output, open('file.txt', 'rb') as input:
    copyfileobj(input, output)

将是我的建议。 它避免了重新实现缓冲机制,并且如果标准库的实现得到改进,您的代码也会获胜。


在 Unix 上,还有一个名为sendfile的非标准化系统调用。 它主要用于将数据从打开的文件发送到套接字(服务 HTTP 请求等)。

Linux 也允许使用它在常规文件之间复制数据。 其他平台没有,请检查 Python 文档和您的手册页。 通过使用系统调用,内核可以复制内容,而无需将缓冲区复制到用户区或从用户区复制缓冲区。

os 模块从 Python 3.3 开始提供os.sendfile() 你可以像这样使用它:

import io
import os

with open('file2.txt', 'wb') as output, open('file.txt', 'rb') as input:
    offset = 0 # instructs sendfile to start reading at start of input
    input_size = input.seek(0, io.SEEK_END)
    os.sendfile(output.fileno(), input.fileno(), offset, input_size)

否则,在 PyPi 上有一个包 pysendfile ,用于实现系统调用。 它的工作原理与上面完全一样,只需将os.sendfile替换为sendfile.sendfile (并import sendfile )。

您的output.write(input.read())版本的唯一潜在问题是文件的大小是否太大而无法将其全部保存在内存中。 您可以使用读取较小批次的循环。

with open('file2.txt', 'wb+') as output, open('file.txt', 'rb') as input:
    while True:
        data = input.read(100000)
        if data == '':  # end of file reached
            break
        output.write(data)

这适用于文本和二进制文件。 但是您需要将b修饰符添加到二进制文件的可移植操作模式中。

虽然这可能不能完全回答您的问题,但对于没有对文件内容进行任何其他处理的纯复制,您应该考虑其他方法,例如shutil模块:

shutil.copy('file.txt', 'file2.txt')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM