《Python编程》笔记专栏现以开源到Gitee,其中包含我编写的示例程序文件和官方示例程序文件,以及md形式的笔记,欢迎各位给个Star。
复制目录树
示例:cpall.py
"""
##############################################################################
用法:“./cpall.py dirFrom dirTo [-m maxFileLoad] [-b blockSize] [-v verbose]”。
递归地复制dirFrom到dirTo下。和Unix命令“cp -r dirFrom dirTo”效果类似,其中假定dirFrom
和dirTo都是目录。
##############################################################################
"""
import os
import sys
import time
MAXFILELOAD = 1024 * 1024
BLOCKSIZE = 1024 * 1024
VERBOSE = 0
def copyFile(
pathFrom,
pathTo,
maxFileLoad=MAXFILELOAD,
blockSize=BLOCKSIZE
):
"""
将单个文件逐字节的从pathFrom复制到pathTo。
使用二进制文件模式防止Unicode解码及换行符转换。
"""
if os.path.getsize(pathFrom) <= maxFileLoad:
open(pathTo, 'wb').write(open(pathFrom, 'rb').read())
else:
fileFrom = open(pathFrom, 'rb')
fileTo = open(pathTo, 'wb')
while True:
bytesFrom = fileFrom.read(blockSize)
if not bytesFrom:
break
fileTo.write(bytesFrom)
fileFrom.close()
fileTo.close()
def copyTree(
dirFrom,
dirTo,
maxFileLoad=MAXFILELOAD,
blockSize=BLOCKSIZE,
verbose=VERBOSE
):
"""
将dirFrom下的内容递归地复制到dirTo,返回(文件数目,目录数目)形式的元组。
为避免在某些平台上目录吗不可解码,可能需要为其名使用字节。
"""
fileCount = dirCount = 0
for filename in os.listdir(dirFrom):
pathFrom = os.path.join(dirFrom, filename)
pathTo = os.path.join(dirTo, filename)
if not os.path.isdir(pathFrom):
try:
if verbose > 1:
print('文件:正在将{}复制到{}'.format(pathFrom, pathTo))
copyFile(pathFrom, pathTo, maxFileLoad, blockSize)
fileCount += 1
except Exception:
print('错误:将{}复制到{},已跳过'.format(pathFrom, pathTo))
print(sys.exc_info()[0], sys.exc_info()[1])
else:
if verbose:
print('目录:正在将{}复制到{}'.format(pathFrom, pathTo))
try:
os.mkdir(pathTo)
except Exception:
print('错误:创建{},已跳过'.format(pathTo))
print(sys.exc_info()[0], sys.exc_info()[1])
below = copyTree(pathFrom, pathTo, maxFileLoad, blockSize, verbose)
fileCount += below[0]
dirCount += below[1]
dirCount += 1
return fileCount, dirCount
def getInt(label, var):
index = sys.argv.index(label) + 1
try:
var = int(sys.argv[index])
except IndexError:
print('错误:命令行参数{}之后无数字')
sys.exit()
except ValueError:
print('错误:命令行参数{}之后不是数字')
sys.exit()
else:
return var
def getArgs(
maxFileLoad=MAXFILELOAD,
blockSize=BLOCKSIZE,
verbose=VERBOSE
):
"""
获取并验证文件命令行参数
"""
if len(sys.argv) < 3:
msg = '使用方法:'
msg += '\n./cpall.py dirFrom dirTo '
msg += '[-m maxFileLoad] [-b blockSize] [-v verbose]'
print(msg)
sys.exit()
dirFrom, dirTo = sys.argv[1:3]
dirFrom, dirTo = map(os.path.abspath, [dirFrom, dirTo])
if not os.path.isdir(dirFrom):
print('错误:dirFrom不是一个目录')
sys.exit()
if os.path.isfile(dirTo):
print('错误:dirTo不是一个目录')
sys.exit()
dirTo = os.path.join(dirTo, os.path.basename(dirFrom))
if not os.path.exists(dirTo):
os.mkdir(dirTo)
print('提示:创建了dirTo')
else:
print('警告:dirTo已存在')
if hasattr(os.path, 'samefile'):
isSame = os.path.samefile(dirFrom, dirTo)
else:
isSame = os.path.abspath(dirFrom) == os.path.abspath(dirTo)
if isSame:
print('错误:dirFrom和dirTo是同一个目录')
sys.exit()
if '-m' in sys.argv:
maxFileLoad = getInt('-m', maxFileLoad)
if '-b' in sys.argv:
blockSize = getInt('-b', blockSize)
if '-v' in sys.argv:
verbose = getInt('-v', verbose)
return dirFrom, dirTo, maxFileLoad, blockSize, verbose
def command():
args = getArgs()
print('参数:')
names = ('dirFrom', 'dirTo', 'maxFileLoad', 'blockSize', 'verbose')
for index in range(len(names)):
print('\t{} -> {}'.format(names[index], args[index]))
print('正在复制')
start = time.time()
fcount, dcount = copyTree(*args)
finish = time.time()
print('复制完成:用时{}s,共复制了{}个文件、{}个目录'.format(finish - start, fcount, dcount))
if __name__ == '__main__':
command()
运行:cpall.py
$ ./cpall.py ../../ /media/beacherhou/Git仓库/ -v 1 -m 1024 -b 1024
提示:创建了dirTo
正在复制
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system复制到/media/beacherhou/Git仓库/my_PP4E/system
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools复制到/media/beacherhou/Git仓库/my_PP4E/system/filetools
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools/tester复制到/media/beacherhou/Git仓库/my_PP4E/system/filetools/tester
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools/tester/Args复制到/media/beacherhou/Git仓库/my_PP4E/system/filetools/tester/Args
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools/tester/Inputs复制到/media/beacherhou/Git仓库/my_PP4E/system/filetools/tester/Inputs
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools/tester/Scripts复制到/media/beacherhou/Git仓库/my_PP4E/system/filetools/tester/Scripts
目录:正在将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/__pycache__复制到/media/beacherhou/Git仓库/my_PP4E/system/__pycache__
复制完成:用时0.21999740600585938s,共复制了103个文件、7个目录
———————————————————————————————————————————
😃 学完博客后,是不是有所启发呢?如果对此还有疑问,欢迎在评论区留言哦。 如果还想了解更多的信息,欢迎大佬们关注我哦,也可以查看我的个人博客网站BeacherHou。
|