Python的shutil模块中文件的复制操作函数详解


Posted in Python onJuly 05, 2016

copy()
chutil.copy(source, destination)
shutil.copy() 函数实现文件复制功能,将 source 文件复制到 destination 文件夹中,两个参数都是字符串格式。如果 destination 是一个文件名称,那么它会被用来当作复制后的文件名称,即等于 复制 + 重命名。举例如下:

>> import shutil
 >> import os
 >> os.chdir('C:\\')
 >> shutil.copy('C:\\spam.txt', 'C:\\delicious')
 'C:\\delicious\\spam.txt'
 >> shutil.copy('eggs.txt', 'C:\\delicious\\eggs2.txt')
 'C:\\delicious\\eggs2.txt'

如代码所示,该函数的返回值是复制成功后的字符串格式的文件路径。

copyfile()
copyfile()将源的内容复制给目标,如果没有权限写目标文件则产生IoError

from shutil import *
from glob import glob
print 'BEFORE:', glob('huanhuan.*')
copyfile('huanhuan.txt', 'huanhuan.txt.copy')
print 'AFTER:', glob('huanhuan.*')

这个函数会打开输入文件进行读写,而不论其类型,所以某些特殊文件不可以用copyfile()复制为新的特殊文件。

>>> ================================ RESTART ================================
>>> 
BEFORE: ['huanhuan.txt']
AFTER: ['huanhuan.txt', 'huanhuan.txt.copy']

copyfile()实际是使用了底层函数copyfileobj()。copyfile()的参数是文件名,copyfileobj()的参数是打开的文件句柄。第三个参数可选,用于读入块的缓冲区长度。

from shutil import *
import os
from StringIO import StringIO
import sys
class VerboseStringIO(StringIO):
  def read(self, n=-1):
    next = StringIO.read(self, n)
    print 'read(%d) bytes' % n
    return next
lorem_ipsum = '''This makes the dependency explicit, limits the scope to the current file and provides faster access to the bit.* functions, too.
It's good programming practice not to rely on the global variable bit being set (assuming some other part of your application has already loaded the module).
The require function ensures the module is only loaded once, in any case.'''
print 'Defalut:'
input = VerboseStringIO(lorem_ipsum)
output = StringIO()
copyfileobj(input, output)
print
print 'All at once:'
input = VerboseStringIO(lorem_ipsum)
output = StringIO()
copyfileobj(input, output, -1)
print
print 'Blocks of 256:'
input = VerboseStringIO(lorem_ipsum)
output = StringIO()
copyfileobj(input, output, 256)

默认行为是使用大数据块读取。使用-1会一次性读取所有输入,或者使用其他正数可以设置特定块的大小。

>>> ================================ RESTART ================================
>>> 
Defalut:
read(16384) bytes
read(16384) bytes

All at once:
read(-1) bytes
read(-1) bytes

Blocks of 256:
read(256) bytes
read(256) bytes
read(256) bytes

类似于UNIX命令行工具cp,copy()函数会用同样的方式解释输出名。如果指定的目标指示一个目录而不是一个文件,会使用源文件的基名在该目录中创建一个新文件。

from shutil import *
import os
dir = os.getcwd()
if not os.path.exists('%s\\example' % dir):
  os.mkdir('%s\\example' % dir)
print 'BEFORE:', os.listdir('example')
copy('huanhuan.txt', 'example')
print 'AFTER:', os.listdir('example')
>>> ================================ RESTART ================================
>>> 
BEFORE: []
AFTER: ['huanhuan.txt']

copy2()

copy2()工作类似copy(),不过复制到新文件的元数据会包含访问和修改时间。

from shutil import *
import os
import time
dir = os.getcwd()
if not os.path.exists('%s\\example' % dir):
  os.mkdir('%s\\example' % dir)
  
def show_file_info(filename):
  stat_info = os.stat(filename)
  print '\tMode  :', stat_info.st_mode
  print '\tCreated :', time.ctime(stat_info.st_ctime)
  print '\tAccessed:', time.ctime(stat_info.st_atime)
  print '\tModified:', time.ctime(stat_info.st_mtime)

print 'SOURCE:'
show_file_info('huanhuan.txt')
copy2('huanhuan.txt', 'example')
print 'DEST:'
show_file_info('%s\\example\\huanhuan.txt' % dir)

文件特性和原文件完全相同。

>>> ================================ RESTART ================================
>>> 
SOURCE:
  Mode  : 33206
  Created : Thu Feb 13 17:42:46 2014
  Accessed: Thu Feb 13 17:42:46 2014
  Modified: Thu Feb 13 17:42:46 2014
DEST:
  Mode  : 33206
  Created : Thu Feb 13 18:29:14 2014
  Accessed: Thu Feb 13 17:42:46 2014
  Modified: Thu Feb 13 17:42:46 2014

   

复制文件元数据
在UNIX创建一个新文件,会根据当前用户的umask接受权限。要把权限从一个文件复制到另一个文件,可以使用copymode()。

from shutil import *
import os
from commands import *
with open('file_to_change.txt', 'wt') as f:
  f.write('i love you')
os.chmod('file_to_change.txt', 0444)
print 'BEFORE:'
print getstatus('file_to_change.txt')
copymode('shutil_copymode.py', 'file_to_change.txt')
print 'AFTER:'
print getstatus('file_to_change.txt')

要复制其他元数据,可以使用copystat()。

from shutil import *
import os
import time
def show_file_info(filename):
  stat_info = os.stat(filename)
  print '\tMode    :', stat_info.st_mode
  print '\tCreated  :', time.ctime(stat_info.st_ctime)
  print '\tAccessed  :', time.ctime(stat_info.st_atime)
  print '\tModified  :', time.ctime(stat_info.st_mtime)
with open('file_to_change.txt', 'wt') as f:
  f.write('i love you')
os.chmod('file_to_Change.txt', 0444)
print 'BEFORE:'
show_file_info('file_to_Change.txt')
copystat('shutil_copystat.py', 'file_to_Change.txt')
print 'AFTER:'
show_file_info('file_to_Change.txt')

使用copystat()只会复制与文件关联的权限和日期。

处理目录树
shutil包含三个函数处理目录树。要把一个目录从一个位置复制到另一个位置,使用copytree()。这会递归遍历源目录树,将文件复制到目标。
copytree()可以将当前这个实现当作起点,在使用前要让它更健壮,可以增加一些特性,如进度条。

from shutil import *
from commands import *
print 'BEFORE:'
print getoutput('ls -rlast /tmp/example')
copytree('../shutil', '/tmp/example')
print '\nAFTER:'
print getoutput('ls -rlast /tmp/example')

symlinks参数控制着符号链接作为链接复制还是文件复制。默认将内容复制到新文件,如果选项为true,会在目标中创建新的符号链接。
要删除一个目录及其内容,可以使用rmtree()。

from shutil import *
from commands import *
print 'BEFORE:'
print getoutput('ls -rlast /tmp/example')
rmtree('/tmp/example')
print '\nAFTER:'
print getoutput('ls -rlast /tmp/example')

将一个文件或目录从一个位置移动到另一个位置,可以使用move()。

from shutil import *
from glob import glob
with open('example.txt', 'wt') as f:
  f.write('i love you')
print 'BEFORE: ', glob('example*')
move('example.txt', 'example.out')
print 'AFTER: ',glob('example*')

其语义与UNIX命令mv类似。如果源与目标都在同一个文件系统内,则会重命名源文件。否则,源文件会复制到目标文件,将源文件删除。

>>> ================================ RESTART ================================
>>> 
BEFORE: ['example', 'example.txt']
AFTER: ['example', 'example.out']
Python 相关文章推荐
python中定义结构体的方法
Mar 04 Python
使用Python脚本和ADB命令实现卸载App
Feb 10 Python
python学习教程之使用py2exe打包
Sep 24 Python
python实现超简单的视频对象提取功能
Jun 04 Python
用python3教你任意Html主内容提取功能
Nov 05 Python
python对于requests的封装方法详解
Jan 03 Python
Python中extend和append的区别讲解
Jan 24 Python
对python_discover方法遍历所有执行的用例详解
Feb 13 Python
numpy.array 操作使用简单总结
Nov 08 Python
python 调试冷知识(小结)
Nov 11 Python
Django的CVB实例详解
Feb 10 Python
python实现定时发送邮件
Dec 23 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
Jul 04 #Python
Python获取暗黑破坏神3战网前1000命位玩家的英雄技能统计
Jul 04 #Python
Python实现代码统计工具(终极篇)
Jul 04 #Python
在win和Linux系统中python命令行运行的不同
Jul 03 #Python
win10系统中安装scrapy-1.1
Jul 03 #Python
使用Python从有道词典网页获取单词翻译
Jul 03 #Python
python中函数传参详解
Jul 03 #Python
You might like
简单示例AJAX结合PHP代码实现登录效果代码
2008/07/25 PHP
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
PDO::inTransaction讲解
2019/01/28 PHP
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
用jquery等比例控制图片宽高的具体实现
2014/01/28 Javascript
javascript实现获取字符串hash值
2015/05/10 Javascript
JavaScript模拟鼠标右键菜单效果
2020/12/08 Javascript
js获取Get值的方法
2016/09/29 Javascript
微信小程序中post方法与get方法的封装
2017/09/26 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
JavaScript原型链与继承操作实例总结
2018/08/24 Javascript
微信小程序实现获取准确的腾讯定位地址功能示例
2019/03/27 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
JavaScript封装单向链表的示例代码
2020/09/17 Javascript
javascript实现下拉菜单效果
2021/02/09 Javascript
Python基于回溯法子集树模板实现8皇后问题
2017/09/01 Python
Python Numpy:找到list中的np.nan值方法
2018/10/30 Python
python实现生成字符串大小写字母和数字的各种组合
2019/01/01 Python
对Pycharm创建py文件时自定义头部模板的方法详解
2019/02/12 Python
Python字符串中删除特定字符的方法
2020/01/15 Python
python dumps和loads区别详解
2020/02/04 Python
浅析Python迭代器的高级用法
2020/07/16 Python
Selenium webdriver添加cookie实现过程详解
2020/08/12 Python
某公司部分笔试题
2013/11/05 面试题
党员教师工作决心书
2014/03/13 职场文书
商场父亲节活动方案
2014/08/27 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
2019消防宣传标语!
2019/07/10 职场文书
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
2021/05/21 Redis
让文件路径提取变得更简单的Python Path库
2021/05/27 Python
React forwardRef的使用方法及注意点
2021/06/13 Javascript