Python 复制文件的方法

Print

Introduction

The requirement: to copy a file or directory to another location

On the surface, this looks simple. And, indeed, it can be quite simple with no need for complications. But, if complications arise, it's worth knowing what your options are. I outline four possibilities below, each with pros and cons, and these don't include some of the more esoteric possibilities such as WMI or the Windows Scripting Host, which might be suitable for you if, say, you were working with them in your code already.

  • If your needs are simple, and you're not bothered about portability, then the os.system approach might well cut the mustard. This will simply call the underlying OS command line and will do whatever that does.
  • If you're after portability and/or prefer to use Python code where possible, then the shutil method is probably the best bet. It uses Python-only code.
  • If you're keen to use the Win32 API where possible, or are concerned not to clobber existing files, then the CopyFile function from the win32file module of the pywin32 extensions may be what you're after.
  • Finally, the Platinum Option is probably to use the shell functionality which will offer the same facilities as Explorer, including animated icons, the recycle bin and renaming on collision.

Simple: use os.system

You can call any command line tool, including the venerable copy and xcopy commands using os.system (or the newer subprocess module).

  • Simple
  • Easy conversion of existing batch scripts etc.
  • Does support directory trees via xcopy / robocopy &.
  • Gives you little control over behaviour or appearance
import os
import tempfile

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

os.system ("copy %s %s" % (filename1, filename2))

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

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

os.system ("xcopy /s %s %s" % (dirname1, dirname2))

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

Portable: use shutil.copy

The shutil module has functions for different kinds of copying, with and without attributes, directory trees and so on.

  • Simple
  • Comes with Python, and therefore portable
  • Relatively naive: will clobber existing files
  • Does support directory trees with a separate function
  • Doesn't make use of extra Win32 functionality, such as animated cursors, rename-on-collision etc.
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"

Win32-specific: use win32file.CopyFile

The win32file module of the pywin32 extensions has everything you could want for manipulating files under Win32 (and quite a bit more, in my experience). In particular, the CopyFile function.

  • Simple
  • As standard as you can get outside of Python itself
  • Allows for abort-on-collision
  • Non-portable (except with things like Wine, presumably)
  • Does not support directory trees (afaict)
import os
import win32file
import tempfile

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

#
# Do a straight copy first, then try to copy without
# failing on collision, then try to copy and fail on
# collision. The first two should succeed; the third
# should fail.
#
win32file.CopyFile (filename1, filename2, 1)
win32file.CopyFile (filename1, filename2, 0)
win32file.CopyFile (filename1, filename2, 1)

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

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

#
# The CopyFile functionality doesn't seem to cope
# with directories.
#
win32file.CopyFile (dirname1, dirname2, 1)

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

Win32 shell: use SHFileOperation

The Windows shell — essentially Explorer and everything that goes with it — has a lot of potential for Windows programmers. It is, though, a bit more involved than perhaps it might be. The pywin32 extensions give access to it via the win32com.shell package. The function of use here is the SHFileOperation, which covers a multitude of shims.

  • Gives access to Explorer's value-added features, such as rename-on-collision etc.
  • Deals transparently with directories
  • (Ahem) I've wrapped some of the functionality in my winshell module.
  • Non-portable (except with things like Wine, presumably)
  • Less-than-intuitive API
import os
from win32com.shell import shell, shellcon
import tempfile

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

#
# Do a straight copy first, then try to copy with
# rename-on-collision, then without. The first two
# should succeed (the second with a confirmation dialog);
# the third should fail.
#
shell.SHFileOperation (
  (0, shellcon.FO_COPY, filename1, filename2, 0, None, None)
)
shell.SHFileOperation (
  (0, shellcon.FO_COPY, filename1, filename2, shellcon.FOF_RENAMEONCOLLISION, None, None)
)
shell.SHFileOperation (
  (0, shellcon.FO_COPY, filename1, filename2, 0, None, None)
)

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

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

#
# The CopyFile functionality doesn't seem to cope
# with directories.
#
shell.SHFileOperation (
  (0, shellcon.FO_COPY, dirname1, dirname2, 0, None, None)
)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值