geekdoc-python-zh/docs/pythoncentral/how-to-copy-a-file-in-pytho...

105 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 如何用 Shutil 在 Python 中复制文件
> 原文:<https://www.pythoncentral.io/how-to-copy-a-file-in-python-with-shutil/>
所以你想知道如何用 Python 复制一个文件?很好!这是非常有用的学习和最复杂的应用程序,你可能会设计至少需要某种形式的复制文件。
## **用 Python 复制单个文件**
好吧,我们开始吧。第一部分将描述如何将单个文件(不是目录)复制到硬盘上的另一个位置。
Python 有一个名为`shutil`的特殊模块,用于简单的高级文件操作,在复制单个文件时非常有用。
下面是一个将单个文件复制到目标文件或文件夹的函数示例(带有错误处理/报告):
```py
import shutil
def copyFile(srcdest):
try:
shutil . copy(srcdest)
# eg. src 和 dest 是同一个文件
除了 shutil错误为 e:
打印('错误:%s' % e)
#例如,源或目标不存在
除了 io 错误为 e:
打印('错误:%s' % e.strerror)
```
就是这样!我们只要调用那个方法,文件就被复制了。如果源文件或目标文件不存在,我们打印一个错误通知用户操作失败。如果源文件和目标文件相同,我们不会复制它们,也不会通知用户操作失败。
### **Python shutil 的不同复制方法**
除了我们上面看到的简单的`copy`方法之外,模块`shutil`还有几个复制文件的方法。
我将在这里详细介绍它们,解释它们之间的区别以及我们可能需要它们的情况。
`shutil.copyfileobj(fsrc, fdst[, buffer_length])`
该功能允许复制带有实际文件对象本身的文件。如果您已经使用内置的`open`函数打开了一个要读取的文件和一个要写入的文件,那么您应该使用`shutil.copyfileobj`。当需要指定复制操作的缓冲区长度时,使用这个函数也很有意义。在复制大文件时,增加缓冲区长度(默认值为 16 KB)可能有助于加快复制操作。
下面提到的所有其他复制函数都会在某个时候调用这个函数。它是“基本”复制方法。
让我们来看一个使用 50 KB、100 KB、500 KB、1 MB、10 MB 和 100 MB 缓冲区大小与普通复制操作进行文件复制的基准测试。我们将测试一个 iso 格式的 3.2 GB 存档文件。
我们将使用这个函数来指定缓冲区的大小:
```py
def copyLargeFile(src, dest, buffer_size=16000):
with open(src, 'rb') as fsrc:
with open(dest, 'wb') as fdest:
shutil.copyfileobj(fsrc, fdest, buffer_size)
```
并且 Ubuntu 内置了`time` bash 命令来为操作计时。
结果如下:
50kb:29.539s
100 KB:27.423s
500 KB:25.245s
1mb:26.261s
10mb:25.521s
100 MB:24.886s
正如您所看到的,缓冲区大小之间有很大的差异。使用 50 KB 的缓冲区比使用 100 MB 的缓冲区花费的时间减少了近 16%。
最佳的缓冲区大小最终取决于可用的 RAM 容量和文件大小。
`shutil.copyfile(src, dst)`
此方法将文件从源位置`src`复制到目标位置`dst`。这与`copy`的不同之处在于,您必须确保目标路径存在,并且还包含文件名。例如,`'/home/'`可能是无效的,因为它是一个目录的名称。`'/home/test.txt'`将是有效的,因为它包含一个文件名。
`shutil.copy(src, dst)`
我们上面使用的`copy`检测目标路径是否包含文件名。如果路径不包含文件名,`copy`在复制操作中使用原始文件名。它还将权限位复制到目标文件。
如果您不确定目标路径的格式,或者想要复制源文件的权限位,您可以使用这个函数。
`shutil.copy2(src, dst)`
这与我们使用的 copy 函数相同,只是它将文件元数据与文件一起复制。元数据包括许可位、最后访问时间、最后修改时间和标志。
如果你想要一个几乎完全相同的文件副本,你可以在`copy`上使用这个函数。
### **Python 文件复制功能对比**
下面我们可以看到`shutil`的文件复制功能的对比,以及它们的不同之处。
| **功能** | **复制元数据** | **拷贝权限** | **可以指定缓冲区** |
| `shutil.copy` | 不 | 是 | 不 |
| `shutil.copyfile` | 不 | 不 | 不 |
| `shutil.copy2` | 是 | 是 | 不 |
| `shutil.copyfileobj` | 不 | 不 | 是 |
复制文件到此就差不多结束了。我希望您能从这篇文章中受益,也希望花时间学习一点 Python 中的文件操作是值得的。
直到下一次!
再见。