105 lines
4.4 KiB
Markdown
105 lines
4.4 KiB
Markdown
# 如何用 Shutil 在 Python 中复制文件
|
||
|
||
> 原文:<https://www.pythoncentral.io/how-to-copy-a-file-in-python-with-shutil/>
|
||
|
||
所以你想知道如何用 Python 复制一个文件?很好!这是非常有用的学习和最复杂的应用程序,你可能会设计至少需要某种形式的复制文件。
|
||
|
||
## **用 Python 复制单个文件**
|
||
|
||
好吧,我们开始吧。第一部分将描述如何将单个文件(不是目录)复制到硬盘上的另一个位置。
|
||
|
||
Python 有一个名为`shutil`的特殊模块,用于简单的高级文件操作,在复制单个文件时非常有用。
|
||
|
||
下面是一个将单个文件复制到目标文件或文件夹的函数示例(带有错误处理/报告):
|
||
|
||
```py
|
||
|
||
import shutil
|
||
def copyFile(src,dest):
|
||
try:
|
||
shutil . copy(src,dest)
|
||
# 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 中的文件操作是值得的。
|
||
|
||
直到下一次!
|
||
|
||
再见。 |