最近在通过视频教程学习python,学到文件操作的时候,老师讲解了如何历用递归来进行文件/文件夹(包括其中所有内容)的复制,然而讲的不是很详细,而且也存在一些bug,我结合自己的理解,对老师教的方法进行了改进,最终总结成了一个比较完整和全面的函数封装,代码如下:
# 复制文件
import os
"""
封装一个copy函数:
功能:传入复制的文件/文件夹夹源路径,和目标路径,将文件夹,整个(包括其中的文件、文件夹)拷贝到目标下
分析:
1.判断源文件夹是否存在,不存在则直接返回False
2.判断目标文件夹是否存在,若不存在则进行创建,若创建不成功,直接返回False
3.判断拿到的源路径和目标路径是否是文件夹
4.如果是文件夹,则遍历其中的文件,并调用copy() 函数自身进行复制(递归),由于当前操作的文件夹的改变,调用时应注意,源路径和目标路径的拼接
5.如果不是文件夹,则直接进行复制即可,并返回 True 或者 False,结束函数
"""
def copy(src, target):
"""
复制指定文件/文件夹到指定目标路径的方法
:param src: 源文件/文件夹
:param target: 目标文件夹
:return: 是否複製成功
"""
try:
if os.path.exists(src):
if not os.path.exists(target):
try:
print('指定目标路径不存在,进行创建')
os.mkdir(target)
except OSError:
print('指定目标路径创建失败')
return False
else:
print('源文件夹不存在')
return False
if not os.path.isdir(target):
print('目标路径不是一个正确的目录')
return False
if os.path.isdir(src):
# 如果是文件夹,那么就在目标路径创建同名文件夹,达到复制文件夹目的
folder_name = os.path.split(src)[1]
target_uri = os.path.join(target, folder_name)
os.mkdir(target_uri)
# 复制完成,需要遍历源文件夹中的文件/文件夹数量
file_list = os.listdir(src)
for file in file_list:
# 组装文件、文件夹复制的目标路径
path = os.path.join(src, file)
if not os.path.isdir(path):
with open(path, 'rb') as read_stream:
container = read_stream.read()
path1 = os.path.join(os.path.join(target, folder_name), file)
with open(path1, 'wb') as write_stream:
write_stream.write(container)
else:
copy(path, target_uri)
else:
file = os.path.split(src)[1]
with open(src, 'rb') as read_stream:
container = read_stream.read()
path1 = os.path.join(target, file)
with open(path1, 'wb') as write_stream:
write_stream.write(container)
print('复制完毕')
return True
except IOError:
print('文件已存在')
'''
可扩展功能:如果要复制的文件/文件夹已存在,则可以提醒用户是否覆盖,若选择是,则调用自定义函数 remove() 删除目标路径下的同名文件/文件夹,
再调用 copy() 进行复制操作,否则取消复制,remove() 函数的实现,同样需要用到递归,与copy() 同理,这里暂不进行编写
input1 = input('文件夹已存在,是否覆盖:y/n(y):')
if input1 == 'y' or input1 == '':
remove(target)
copy(src, target)
'''
return False
# 调用函数
src_path1 = r'E:\python_test_files\ddd'
# src_path1 = r'E:\python_test_files\a.txt'
target_path1 = r'E:\python_test_files\haha\aaa\bbb\ccc'
print(copy(src_path1, target_path1))
如同此代码注释中所说,该函数能够正确的复制文件或者文件夹(包括其中的文件和文件夹)到指定目录,但是有一个问题没有解决,就是如果目标路径下有同名文件或文件夹时,函数停止复制操作,而更加完善的做法是:提示用户文件/文件夹已存在,是否进行覆盖,然后根据用户选择来进行覆盖(就是先把原来的文件/文件夹删除,再粘贴,当然,删除同样需要进行递归删除)或者取消操作。
当然,即便如此,我的代码功能还有诸多为完善的地方,希望能把自己的学习成果多多分享,相互学习,共同进步