题 如何在python中复制文件?


如何在Python中复制文件?我找不到任何东西 os


1469
2017-09-23 19:23


起源


似乎cp不是系统调用,因此不属于os模块。它是一个shell命令,因此它被放在shutil模块中。 - waldol1


答案:


shutil 有很多方法可以使用。其中之一是:

from shutil import copyfile

copyfile(src, dst)

复制名为的文件的内容 src 到一个名为的文件 dst。目的地位置必须是可写的;否则,一个 IOError 异常将被提出。如果 dst 已经存在,它将被替换。使用此功能无法复制特殊文件,如字符或块设备和管道。 src 和 dst 是作为字符串给出的路径名。


1788
2017-09-23 19:25



copy和copyfile有什么区别? - Matt
在副本(src,dst)中,dst可以是目录。 - Owen
请注意,并非所有元数据都会被复制,具体取决于您的平台。 - Kevin Horn
来自shutil import copyFile ImportError:无法导入名称copyFile - Mona Jalal
@MonaJalal这是区分大小写的,不要使用资本F. - antonagestam


-----------------------------------------------------------------------------------
| Function          |Copies Metadata|Copies Permissions|Can Use Buffer|Dest Dir OK
-----------------------------------------------------------------------------------
| shutil.copy       |      No       |        Yes       |      No      |    Yes
-----------------------------------------------------------------------------------
| shutil.copyfile   |      No       |        No        |      No      |    No
-----------------------------------------------------------------------------------
| shutil.copy2      |      Yes      |        Yes       |      No      |    Yes
-----------------------------------------------------------------------------------
| shutil.copyfileobj|      No       |        No        |      Yes     |    No
-----------------------------------------------------------------------------------

554
2018-05-20 20:01



也可以将该副本和copy2接受目录添加为目标,而不是需要指定完整名称的copyfile。 - Conchylicultor
@jezrael从文档中摘录: dst must be the complete target file name; look at shutil.copy() for a copy that accepts a target directory path. (这里: docs.python.org/3/library/shutil.html#shutil.copyfile) - Conchylicultor


copy2(src,dst) 通常比有用更有用 copyfile(src,dst) 因为:

  • 它允许 dst 成为一个 目录 (而不是完整的目标文件名),在这种情况下 基本名 的 src 用于创建新文件;
  • 它保留了文件元数据中的原始修改和访问信息(mtime和atime)(但是,这会带来轻微的开销)。

这是一个简短的例子:

import shutil
shutil.copy2('/src/dir/file.ext', '/dst/dir/newname.ext') # complete target filename given
shutil.copy2('/src/file.ext', '/dst/dir') # target filename is /dst/dir/file.ext

549
2017-09-23 19:29



虽然文档警告copy2不保留所有元数据,但这正是我需要的,因为我想要列出的项目。谢谢! - sage
你的答案有点欺骗性。你选择的话 shutil.copy2('/dir/file.ext', '/new/dir') 建议copy2将创建一个新目录。但在这种情况下 dir 必须已经作为一个存在 目录 要不然 file.ext 将被复制到一个新的 文件 叫 dir。 - Matthew Alpert
我试图从100万个文件中随机复制100k文件。 copyfile 比...快得多 copy2 - Vijay
我是否正确地假设 shutil.copy2('/dir/file.ext', '/new/dir/') (在目标路径之后使用斜杠)将消除是否复制到名为“dir”的新文件或将文件放入该名称的目录中的歧义? - Zak
@Vijay我认为这种开销是由于复制了元数据。 - Sheljohn


复制文件是一个相对简单的操作,如下面的示例所示,但您应该使用 shutil stdlib模块 为了那个原因。

def copyfileobj_example(source, dest, buffer_size=1024*1024):
    """      
    Copy a file from source to dest. source and dest
    must be file-like objects, i.e. any object with a read or
    write method, like for example StringIO.
    """
    while True:
        copy_buffer = source.read(buffer_size)
        if not copy_buffer:
            break
        dest.write(copy_buffer)

如果你想通过文件名复制,你可以这样做:

def copyfile_example(source, dest):
    # Beware, this example does not handle any edge cases!
    with open(source, 'rb') as src, open(dest, 'wb') as dst:
        copyfileobj_example(src, dst)

73
2017-09-24 07:21



我刚才注意到模块被称为shutil(单数)而不是shutils(复数),事实上它 是 在Python 2.3中。不过我把这个功能留在这里作为例子。 - pi.
复制文件 内容 是一个简单的操作。使用元数据复制文件绝不是直截了当的,如果您想要跨平台,则更是如此。 - LaC
真正。查看shutil文档,copyfile函数也不会复制元数据。 - pi.
顺便说一句,如果你想在两个类似文件的对象之间复制内容,那就是 shutil.copyfileobj(fsrc, fdst) - Haroldo_OK
是的,我不确定为什么你不会只是复制的来源 shutil.copyfileobj。另外,你没有 try, finally 处理异常后关闭文件。但是,我会说,你的函数根本不应该负责打开和关闭文件。这应该是一个包装函数,就像如何 shutil.copyfile 包装 shutil.copyfileobj。 - ErlVolton


使用 shutil模块

copyfile(src, dst)

将名为src的文件的内容复制到名为dst的文件中。目的地位置必须是可写的;否则,将引发IOError异常。如果dst已经存在,它将被替换。使用此功能无法复制特殊文件,如字符或块设备和管道。 src和dst是以字符串形式给出的路径名。

看一眼 的filesys 用于标准Python模块中可用的所有文件和目录处理函数。


47
2017-09-23 19:27





您可以使用其中一个复制功能 shutil 包:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
函数保留支持接受其他副本
                      权限目录dest。文件obj元数据
-------------------------------------------------- ----------------------------
shutil.copy                                            ☐☐
shutil.copy2                                           ☐
shutil.copyfile          ☐☐☐☐
shutil.copyfileobj       ☐☐☐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

例:

import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')

40
2017-07-09 11:50





目录和文件复制示例 - 来自Tim Golden的Python Stuff:

http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

import os
import shutil
import tempfile

filename1 = tempfile.mktemp (".txt")
open (filename1, "w").close ()
filename2 = filename1 + ".copy"
print filename1, "=>", filename2

shutil.copy (filename1, filename2)

if os.path.isfile (filename2): print "Success"

dirname1 = tempfile.mktemp (".dir")
os.mkdir (dirname1)
dirname2 = dirname1 + ".copy"
print dirname1, "=>", dirname2

shutil.copytree (dirname1, dirname2)

if os.path.isdir (dirname2): print "Success"

36
2018-03-15 10:11





看模块 shutil。 它包含功能 复制文件SRCDST


21
2017-09-23 19:27





在Python中,您可以使用复制文件


import os
import shutil
import subprocess

1)使用复制文件 shutil 模

shutil.copyfile签名

shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)

# example    
shutil.copyfile('source.txt', 'destination.txt')

shutil.copy签名

shutil.copy(src_file, dest_file, *, follow_symlinks=True)

# example
shutil.copy('source.txt', 'destination.txt')

shutil.copy2签名

shutil.copy2(src_file, dest_file, *, follow_symlinks=True)

# example
shutil.copy2('source.txt', 'destination.txt')  

shutil.copyfileobj签名

shutil.copyfileobj(src_file_object, dest_file_object[, length])

# example
file_src = 'source.txt'  
f_src = open(file_src, 'rb')

file_dest = 'destination.txt'  
f_dest = open(file_dest, 'wb')

shutil.copyfileobj(f_src, f_dest)  

2)使用复制文件 os 模

os.popen签名

os.popen(cmd[, mode[, bufsize]])

# example
# In Unix/Linux
os.popen('cp source.txt destination.txt') 

# In Windows
os.popen('copy source.txt destination.txt')

os.system签名

os.system(command)


# In Linux/Unix
os.system('cp source.txt destination.txt')  

# In Windows
os.system('copy source.txt destination.txt')

3)使用复制文件 subprocess 模

subprocess.call签名

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.call('cp source.txt destination.txt', shell=True) 

# In Windows
status = subprocess.call('copy source.txt destination.txt', shell=True)

subprocess.check_output签名

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.check_output('cp source.txt destination.txt', shell=True)

# In Windows
status = subprocess.check_output('copy source.txt destination.txt', shell=True)


20
2018-01-22 03:05





你可以用 os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')

或者就像我做的那样,

os.system('cp '+ rawfile + ' rawdata.dat')

哪里 rawfile 是我在程序中生成的名称。

这是一个仅限Linux的解决方案


13
2017-12-19 23:18



这是不可移植的,因为你只需要使用shutil就不必要了。 - Corey Goldberg
即便 shutil 不可用 - subprocess.run()(不 shell=True!)是更好的选择 os.system()。 - maxschlepzig


对于大文件,我所做的是逐行读取文件并将每行读入数组。然后,一旦数组达到一定大小,将其附加到新文件。

for line in open("file.txt", "r"):
    list.append(line)
    if len(list) == 1000000: 
        output.writelines(list)
        del list[:]

8
2018-05-25 05:11



这似乎有点多余,因为作者应该处理缓冲。 for l in open('file.txt','r'): output.write(l) 应该找工作;只需根据需要设置输出流缓冲区。或者你可以通过循环尝试来获取字节数 output.write(read(n)); output.flush() 哪里 n 是您一次要写入的字节数。这两个也没有条件来检查哪个是奖金。 - owns
是的,但我认为这可能更容易理解,因为它复制整行而不是它们的一部分(如果我们不知道每行有多少字节)。 - ytpillai
非常真实。用于教学和编码效率的编码是非常不同的。 - owns
@owns一年后加入这个问题, writelines() 表现略胜一筹 write() 因为我们不会浪费时间一致地打开新的文件流,而是将新行写为一个大的bytefeed。 - ytpillai
看着源 - writelines调用write, hg.python.org/cpython/file/c6880edaf6f3/Modules/_io/bytesio.c。此外,文件流已经打开,因此每次写入都不需要重新打开。 - owns