status

草稿

清风 & liz; 100%

PCS212 shutil

概述

shutil模块提供了一些高层次的文件操作,比如复制,设置权限,删除等等.

使用

copyfile()

copyfile()将源文件内容完全复制给目标文件.如果没有写入目标文件的权限,会引起IOError.另外,对于一些特殊文件,使用copyfile()是不能被复制成新的特殊文件的.

   1 import os
   2 from shutil import *
   3 
   4 print 'BEFORE:', os.listdir(os.getcwd())
   5 copyfile('pcs-212-1.py', 'pcs-212-1.py.copy')
   6 print 'AFTER:', os.listdir(os.getcwd())

~$ python pcs-212-1.py 
BEFORE: ['pcs-212-1.py', 'pcs-212.moin']
AFTER: ['pcs-212-1.py.copy', 'pcs-212-1.py', 'pcs-212.moin']

copyfile()其实是底层调用了copyfileobj()函式.文件名参数传递给copyfile()后,进而将此文件句柄传递给copyfileobj()并由它真正完成文件复制.

copy()

copy()函式类似于Unix命令cp,将源文件复制一个目标文件.和copyfile()不同的是,如果目标参数是一个目录而不是文件,那么在这个目录中复制一个源文件副本(它与源文件同名).另外,文件的权限也随之复制.

   1 import os
   2 from shutil import *
   3 
   4 os.mkdir('example')
   5 print 'BEFORE:', os.listdir('example')
   6 copy('pcs-212-2.py', 'example')
   7 print 'AFTER:', os.listdir('example')

运行结果:

~$ python pcs-212-2.py 
BEFORE: []
AFTER: ['pcs-212-2.py']

同时还会在当前目录下面创建一个example目录,并把pcs-212-2.py文件copy到example目录里面

copy2()

copy2()函式类似于copy(),但不同于copy()的地方是,copy2()将一些元信息,如文件最后一次被读取时间和修改时间等,也复制给新文件.

   1 import os
   2 import time
   3 from shutil import *
   4 
   5 def show_file_info(filename):
   6     stat_info = os.stat(filename)
   7     print '\tMode    :', stat_info.st_mode
   8     print '\tCreated :', time.ctime(stat_info.st_ctime)
   9     print '\tAccessed:', time.ctime(stat_info.st_atime)
  10     print '\tModified:', time.ctime(stat_info.st_mtime)
  11 
  12 os.mkdir('example')
  13 print 'SOURCE:'
  14 show_file_info('pcs-212-3.py')
  15 copy2('pcs-212-3.py', 'example')
  16 print 'DEST:'
  17 show_file_info('example/pcs-212-3.py')

运行结果如下,可以看到新文件的元信息和源文件的是一样的:

~$ python pcs-212-3.py 
SOURCE:
        Mode    : 33188
        Created : Sun Sep 14 16:49:31 2008
        Accessed: Sun Sep 14 16:49:33 2008
        Modified: Sun Sep 14 16:49:31 2008
DEST:
        Mode    : 33188
        Created : Sun Sep 14 16:49:39 2008
        Accessed: Sun Sep 14 16:49:33 2008
        Modified: Sun Sep 14 16:49:31 2008

copymode()

在Unix下,一个新创建的文件的权限会根据当前用户的umask值来设置.这里可以使用copymode()来实现被创建的文件具有umask值,而不是源文件的权限.

   1 from commands import *
   2 from shutil import *
   3 
   4 print 'BEFORE:', getstatus('file_to_change.txt')
   5 copymode('pcs-212-4.py', 'file_to_change.txt')
   6 print 'AFTER :', getstatus('file_to_change.txt')

首先创建一个文件file_to_change.txt.然后对其权限做些修改:

~$ touch file_to_change.txt
~$ chmod ugo+w file_to_change.txt

然后,运行刚才的示例脚本:

~$ python pcs-212-4.py 
BEFORE: -rw-rw-rw- 1 shengyan shengyan 0 2008-09-14 16:54 file_to_change.txt
AFTER : -rw-r--r-- 1 shengyan shengyan 0 2008-09-14 16:54 file_to_change.txt

可以看到两个文件的权限是不一样的,新的file_to_change.txt的权限设置是与普通新文件的权限一致.

copystat()

copystat()函式可以复制文件的其他元信息(权限,最后读取时间,最后修改时间等).它和copy2()函式很类似.

   1 import os
   2 from shutil import *
   3 import time
   4 
   5 def show_file_info(filename):
   6     stat_info = os.stat(filename)
   7     print '\tMode    :', stat_info.st_mode
   8     print '\tCreated :', time.ctime(stat_info.st_ctime)
   9     print '\tAccessed:', time.ctime(stat_info.st_atime)
  10     print '\tModified:', time.ctime(stat_info.st_mtime)
  11 
  12 print 'BEFORE:'
  13 show_file_info('file_to_change.txt')
  14 copystat('pcs-212-5.py', 'file_to_change.txt')
  15 print 'AFTER :'
  16 show_file_info('file_to_change.txt')

运行结果如下:

~$ python pcs-212-5.py 
BEFORE:
        Mode    : 33188
        Created : Sun Sep 14 16:54:35 2008
        Accessed: Sun Sep 14 16:54:36 2008
        Modified: Sun Sep 14 16:54:09 2008
AFTER :
        Mode    : 33188
        Created : Sun Sep 14 16:58:44 2008
        Accessed: Sun Sep 14 16:58:44 2008
        Modified: Sun Sep 14 16:58:42 2008

copytree()

使用copytree()来复制目录,它会递归复制整个目录结构.目标目录必须不存在.其中的symlinks参数控制符号链接是否作为链接或文件被复制,默认是将其内容复制成一个新文件.如果此选项为true,新的链接会在目标目录中创建.

   1 from commands import *
   2 from shutil import *
   3 
   4 print 'BEFORE:'
   5 print getoutput('ls -rlast ./example_other')
   6 copytree('example', './example_other')
   7 print 'AFTER:'
   8 print getoutput('ls -rlast ./example_other')

运行结果:

~$ python pcs-212-6.py 
BEFORE:
ls: 无法访问./example_other: 没有该文件或目录
AFTER:
总用量 12
4 -rw-r--r-- 1 shengyan shengyan  473 2008-09-14 16:49 pcs-212-3.py
4 drwxr-xr-x 2 shengyan shengyan 4096 2008-09-14 16:49 .
4 drwxr-xr-x 5 shengyan shengyan 4096 2008-09-14 17:04 ..

rmtree()

使用rmtree()可以删除整个目录.若其中产生错误,会作为异常抛出.但是如果它的第二个参数是目录,那么产生的错误会被忽略,第三个参数可以指定为一个特殊出错处理函式句柄.

   1 from commands import *
   2 from shutil import *
   3 
   4 print 'BEFORE:'
   5 print getoutput('ls -rlast ./example_other')
   6 rmtree('example_other', './example_other')
   7 print 'AFTER:'
   8 print getoutput('ls -rlast ./example_other')

~$ python pcs-212-7.py 
BEFORE:
总用量 12
4 -rw-r--r-- 1 shengyan shengyan  473 2008-09-14 16:49 pcs-212-3.py
4 drwxr-xr-x 2 shengyan shengyan 4096 2008-09-14 16:49 .
4 drwxr-xr-x 5 shengyan shengyan 4096 2008-09-14 17:04 ..
AFTER:
ls: 无法访问./example_other: 没有该文件或目录

move()

移动文件或目录可以使用move(),这类似于Unix命令mv.如果源文件或目录和目标文件或目录在同一个文件系统下,那么源文件或目录会直接重命名,否则源文件或目录会复制到目标文件或目录,接着删除源文件或目录.

   1 import os
   2 from shutil import *
   3 
   4 print 'BEFORE: example : ', os.listdir('example')
   5 move('example', 'example2')
   6 print 'AFTER : example2: ', os.listdir('example2')

~$ python pcs-212-8.py 
BEFORE: example :  ['pcs-212-3.py']
AFTER : example2:  ['pcs-212-3.py']