Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2342316
  • 博文数量: 321
  • 博客积分: 3440
  • 博客等级: 中校
  • 技术积分: 2992
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-24 09:08
个人简介

我就在这里

文章分类

全部博文(321)

文章存档

2015年(9)

2014年(84)

2013年(101)

2012年(25)

2011年(29)

2010年(21)

2009年(6)

2008年(23)

2007年(23)

分类: Python/Ruby

2013-02-21 13:22:39

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  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  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  function from the win32file module of the pywin32 extensions may be what you're after.
  • Finally, the Platinum Option is probably to use the  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  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  extensions has everything you could want for manipulating files under Win32 (and quite a bit more, in my experience). In particular, the  function.

  • Simple
  • As standard as you can get outside of Python itself
  • Allows for abort-on-collision

  • Non-portable (except with things like , 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  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  module.

  • Non-portable (except with things like , 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"
转自:

阅读(2795) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~