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