Python的shutil模块中文件的复制操作函数详解
copy()
chutil.copy(source,destination)
shutil.copy()函数实现文件复制功能,将source文件复制到destination文件夹中,两个参数都是字符串格式。如果destination是一个文件名称,那么它会被用来当作复制后的文件名称,即等于复制+重命名。举例如下:
>>importshutil >>importos >>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
fromshutilimport* fromglobimportglob 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()的参数是打开的文件句柄。第三个参数可选,用于读入块的缓冲区长度。
fromshutilimport* importos fromStringIOimportStringIO importsys classVerboseStringIO(StringIO): defread(self,n=-1): next=StringIO.read(self,n) print'read(%d)bytes'%n returnnext lorem_ipsum='''Thismakesthedependencyexplicit,limitsthescopetothecurrentfileandprovidesfasteraccesstothebit.*functions,too. It'sgoodprogrammingpracticenottorelyontheglobalvariablebitbeingset(assumingsomeotherpartofyourapplicationhasalreadyloadedthemodule). Therequirefunctionensuresthemoduleisonlyloadedonce,inanycase.''' print'Defalut:' input=VerboseStringIO(lorem_ipsum) output=StringIO() copyfileobj(input,output) print print'Allatonce:' input=VerboseStringIO(lorem_ipsum) output=StringIO() copyfileobj(input,output,-1) print print'Blocksof256:' input=VerboseStringIO(lorem_ipsum) output=StringIO() copyfileobj(input,output,256)
默认行为是使用大数据块读取。使用-1会一次性读取所有输入,或者使用其他正数可以设置特定块的大小。
>>>================================RESTART================================ >>> Defalut: read(16384)bytes read(16384)bytes Allatonce: read(-1)bytes read(-1)bytes Blocksof256: read(256)bytes read(256)bytes read(256)bytes
类似于UNIX命令行工具cp,copy()函数会用同样的方式解释输出名。如果指定的目标指示一个目录而不是一个文件,会使用源文件的基名在该目录中创建一个新文件。
fromshutilimport* importos dir=os.getcwd() ifnotos.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(),不过复制到新文件的元数据会包含访问和修改时间。
fromshutilimport* importos importtime dir=os.getcwd() ifnotos.path.exists('%s\\example'%dir): os.mkdir('%s\\example'%dir) defshow_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:ThuFeb1317:42:462014 Accessed:ThuFeb1317:42:462014 Modified:ThuFeb1317:42:462014 DEST: Mode:33206 Created:ThuFeb1318:29:142014 Accessed:ThuFeb1317:42:462014 Modified:ThuFeb1317:42:462014
复制文件元数据
在UNIX创建一个新文件,会根据当前用户的umask接受权限。要把权限从一个文件复制到另一个文件,可以使用copymode()。
fromshutilimport* importos fromcommandsimport* withopen('file_to_change.txt','wt')asf: f.write('iloveyou') os.chmod('file_to_change.txt',0444) print'BEFORE:' printgetstatus('file_to_change.txt') copymode('shutil_copymode.py','file_to_change.txt') print'AFTER:' printgetstatus('file_to_change.txt')
要复制其他元数据,可以使用copystat()。
fromshutilimport* importos importtime defshow_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) withopen('file_to_change.txt','wt')asf: f.write('iloveyou') 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()可以将当前这个实现当作起点,在使用前要让它更健壮,可以增加一些特性,如进度条。
fromshutilimport* fromcommandsimport* print'BEFORE:' printgetoutput('ls-rlast/tmp/example') copytree('../shutil','/tmp/example') print'\nAFTER:' printgetoutput('ls-rlast/tmp/example')
symlinks参数控制着符号链接作为链接复制还是文件复制。默认将内容复制到新文件,如果选项为true,会在目标中创建新的符号链接。
要删除一个目录及其内容,可以使用rmtree()。
fromshutilimport* fromcommandsimport* print'BEFORE:' printgetoutput('ls-rlast/tmp/example') rmtree('/tmp/example') print'\nAFTER:' printgetoutput('ls-rlast/tmp/example')
将一个文件或目录从一个位置移动到另一个位置,可以使用move()。
fromshutilimport* fromglobimportglob withopen('example.txt','wt')asf: f.write('iloveyou') print'BEFORE:',glob('example*') move('example.txt','example.out') print'AFTER:',glob('example*')
其语义与UNIX命令mv类似。如果源与目标都在同一个文件系统内,则会重命名源文件。否则,源文件会复制到目标文件,将源文件删除。
>>>================================RESTART================================ >>> BEFORE:['example','example.txt'] AFTER:['example','example.out']