Python 复制文件的方法

来源:互联网 发布:日漫中的中国知乎 编辑:程序博客网 时间:2024/06/01 07:49

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 osimport tempfilefilename1 = tempfile.mktemp (".txt")open (filename1, "w").close ()filename2 = filename1 + ".copy"print filename1, "=>", filename2os.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, "=>", dirname2os.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 osimport shutilimport tempfilefilename1 = tempfile.mktemp (".txt")open (filename1, "w").close ()filename2 = filename1 + ".copy"print filename1, "=>", filename2shutil.copy (filename1, filename2)if os.path.isfile (filename2): print "Success"dirname1 = tempfile.mktemp (".dir")os.mkdir (dirname1)dirname2 = dirname1 + ".copy"print dirname1, "=>", dirname2shutil.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 osimport win32fileimport tempfilefilename1 = 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 osfrom win32com.shell import shell, shellconimport tempfilefilename1 = 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"

原创粉丝点击