Python实现目录复制的三种方法:递归、深度遍历与广度遍历
本文详细介绍Python中实现目录复制的三种核心方法:递归、深度优先遍历(DFS)和广度优先遍历(BFS)。文章对比了三种算法在栈/队列使用、路径处理及文件复制逻辑上的差异,提供了完整的代码示例与关键参数说明,帮助开发者根据实际需求选择最高效的目录同步方案。
目录复制概述
复制目录操作通常涉及包含多层子目录的复杂结构。
实现该功能主要有三种方法:递归调用、深度优先遍历(DFS)以及广度优先遍历(BFS)。
以下重点解析深度遍历与广度遍历的具体实现思路。
深度与广度遍历实现思路
核心思路如下:
首先获取源目录下的所有子级目录,并据此构建目标目录对应的子级路径结构。
具体步骤1.1:初始化两个数据结构(栈或队列),将源目录路径和目标目录路径分别加入其中。通常使用append方法,将元素添加至栈顶或队列尾部。
步骤1.2:在深度遍历模式下,从栈顶取出一个源路径进行判断,同时以相同方式从栈中取出对应的目标路径。由于栈和队列在逻辑上均类似列表,均可通过列表结构实现此过程。
在广度遍历模式下,从队列前端取出一个源路径进行判断,同时以相同方式从队列前端取出对应的目标路径。
步骤2:判断当前处理的源路径指向的是否为文件。
步骤2.1:若目标子级文件不存在,或者虽然存在但文件大小与源文件不一致,则执行复制操作。
步骤3:判断当前处理的源路径指向的是否为目录。
步骤3.1:在递归方法中,调用函数自身,将当前子目录视为新的源文件,递归复制至目标子目录。
步骤3.2:在深度遍历和广度遍历中,将处理完的源目录和目标目录路径再次添加(append)到栈或队列的后部,以便继续处理。
深度与广度遍历代码示例
# 深度遍历 广度遍历(仅取出来的方式不一样)
# 导入模块
import os, collections
def copyDir(sourcePath,targetPath):
# 传入原目录,和需要复制后的目标目录
# 判断需要复制的目录是否存在,如果不存在就返回
if not os.path.isdir(sourcePath):
return '源目录不存在'
# 创建两个栈,一个用来存放原目录路径,另一个用来存放需要复制的目标目录
sourceStack = collections.deque()
sourceStack.append(sourcePath)
targetStack = collections.deque()
targetStack.append(targetPath)
# 创建一个循环当栈里面位空时结束循环
while True:
if len(sourceStack) == 0:
break
# 将路径从栈的上部取出
sourcePath = sourceStack.pop() #sourcePath = sourceStack.popleft()
# 遍历出该目录下的所有文件和目录
listName = os.listdir(sourcePath)
# 将目录路径取出来
targetPath = targetStack.pop() #targetPath = targetStack.popleft()
# 判断该目标目录是否存在,如果不存在就创建
if not os.path.isdir(targetPath):
os.makedirs(targetPath)
# 遍历目录下所有文件组成的列表,判断是文件,还是目录
for name in listName:
# 拼接新的路径
sourceAbs = os.path.join(sourcePath, name)
targetAbs = os.path.join(targetPath, name)
# 判断是否时目录
if os.path.isdir(sourceAbs):
# 判断目标路径是否存在,如果不存在就创建一个
if not os.path.exists(targetAbs):
os.makedirs(targetAbs)
# 将新的目录添加到栈的顶部
sourceStack.append(sourceAbs)
targetStack.append(targetAbs)
# 判断是否是文件
if os.path.isfile(sourceAbs):
# 1.如果目标子级文件不存在 或者目标子级文件存在但是该文件与原子级文件大小不一致 则需要复制
if (not os.path.exists(targetAbs)) or (os.path.exists(targetAbs) and os.path.getsize(targetAbs) != os.path.getsize(targetAbs)):
rf = open(sourceAbs, mode='rb')
wf = open(targetAbs, mode='wb')
while True:
# 一点一点读取,防止当文件较大时候内存吃不消
content = rf.read(1024*1024*10)
if len(content) == 0:
break
wf.write(content)
# 写入缓冲区时候手动刷新一下,可能会加快写入
wf.flush()
# 读写完成关闭文件
rf.close()
wf.close()
# 传入需要复制的目录和需要复制到的目标目录
sPath = ""
tPath = ""
copyDir(sPath,tPath)
递归遍历实现思路
接下来介绍递归遍历的具体实现。
递归逻辑如下:
1. 定义一个用于复制目录的函数,该函数需接收源目录和目标目录作为参数。
2. 检查源目录是否存在,若不存在则终止执行。
3. 检查目标目录是否存在,若不存在则创建该目录。
4. 遍历源目录下的所有条目。
递归遍历代码示例
import os
def copyDir(sourceDir,targetDir):
if not os.path.isdir(sourceDir):
return "源目录不存在"
if not os.path.exists(targetDir):
os.makedirs(targetDir)
listName = os.listdir(sourceDir)
for name in listName:
sourceAbs = os.path.join(sourceDir,name)
targetAbs = os.path.join(targetDir,name)
if os.path.isdir(sourceAbs):
#创建目标目录
if not os.path.exists(targetAbs):
os.makedirs(targetAbs)
copyDir(sourceAbs,targetAbs)
if os.path.isfile(sourceAbs):
# 1.如果目标子级文件不存在 或者 目标子级文件存在但是该文件与原子级文件大小不一致 则需要复制
if (not os.path.exists(targetAbs)) or (os.path.exists(targetAbs) and os.path.getsize(targetAbs) != os.path.getsize(sourceAbs)):
rf = open(sourceAbs,mode="rb")
wf = open(targetAbs,mode="wb")
while True:
content = rf.read(1024*1024*10)
if len(content) == 0:
break
wf.write(content)
wf.flush()
rf.close()
wf.close()
# 测试
sPath = ""
tPath = ""
copyDir(sPath,tPath)
以上关于Python实现目录复制的三种方法小结完毕,希望能为读者提供参考,欢迎支持相关技术社区。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









