使用python解决文件复制的问题
问题
假设你的老板给了你一个任务:
给你一组文件夹,让你把文件夹里面所有的文件都复制出来
如果文件夹的数目与深度比较小还好,但是如果文件夹的数目或深度都非常大,像下面这样的,是会死人的!!
![](https://i.imgur.com/xUzMqTA.png)
一个文件夹一个文件夹的找,最后会吐的
因为这种重复的无意义的劳动其实挺浪费时间的,所以就想了一下能不能写个脚本什么的自动去寻找并复制所有文件。
分析
第一步假设文件夹的根目录为root,需要找到该root下非空文件夹文件中的所有文件,嗯?这不就是树的遍历么,好,于是方法就有了。
#-*- coding:utf-8 -*-
import os
import re
path = os.path.abspath('.')
global PathList
PathList = []
def Recursive(path): #使用递归方法返回所有文件的目录
path = path
if os.path.isfile(path):
PathList.append(path)
else:
L = os.listdir(path)
for i in xrange(len(L)):
Recursive(str(path) + '\\' + str(L[i]))
return PathList
pali = Recursive(path)
for i in pali:
print i
输出来的效果是这样的:
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
========== RESTART: C:\Users\whats\Documents\vscode\fileextract.py ==========
C:\Users\whats\Documents\vscode\.git\config
C:\Users\whats\Documents\vscode\.git\description
C:\Users\whats\Documents\vscode\.git\HEAD
C:\Users\whats\Documents\vscode\.git\hooks\applypatch-msg.sample
C:\Users\whats\Documents\vscode\.git\hooks\commit-msg.sample
C:\Users\whats\Documents\vscode\.git\hooks\post-update.sample
C:\Users\whats\Documents\vscode\.git\hooks\pre-applypatch.sample
C:\Users\whats\Documents\vscode\.git\hooks\pre-commit.sample
C:\Users\whats\Documents\vscode\.git\hooks\pre-push.sample
C:\Users\whats\Documents\vscode\.git\hooks\pre-rebase.sample
C:\Users\whats\Documents\vscode\.git\hooks\pre-receive.sample
C:\Users\whats\Documents\vscode\.git\hooks\prepare-commit-msg.sample
C:\Users\whats\Documents\vscode\.git\hooks\update.sample
C:\Users\whats\Documents\vscode\.git\index
C:\Users\whats\Documents\vscode\.git\info\exclude
C:\Users\whats\Documents\vscode\.git\objects\34\ac762ac837ef7d647a81b525fbd6da1414c5b7
C:\Users\whats\Documents\vscode\123.png
C:\Users\whats\Documents\vscode\ACM\AdjustLine.py
C:\Users\whats\Documents\vscode\ACM\Binarycount.py
C:\Users\whats\Documents\vscode\ACM\buyhat.py
C:\Users\whats\Documents\vscode\ACM\ColorPlant.py
C:\Users\whats\Documents\vscode\ACM\DoublePocess.py
C:\Users\whats\Documents\vscode\ACM\JumpStep.py
C:\Users\whats\Documents\vscode\ACM\justiceoperator.py
C:\Users\whats\Documents\vscode\ACM\MagicRing.py
C:\Users\whats\Documents\vscode\ACM\point24.py
C:\Users\whats\Documents\vscode\ACM\rememberdict.py
C:\Users\whats\Documents\vscode\ACM\removesame.py
C:\Users\whats\Documents\vscode\ACM\rush for company.py
C:\Users\whats\Documents\vscode\ACM\sudoku.py
C:\Users\whats\Documents\vscode\fileextract.py
C:\Users\whats\Documents\vscode\lottery logistics\getNum.py
C:\Users\whats\Documents\vscode\lottery logistics\makrov.py
输出了所有文件的绝对路径,有了文件的绝对路径就可以对文件进行复制操作了,这里有个题外话,当时测试的时候多写了个代码
with open(i, 'wb') as f:
f.write()
于是我这个程序运行目录下所有的文件全变成了0kb图片都没放过qwq,心塞
文件复制
好了,其实输出所有目录的空文件比较简单,但是复制文件就是一件很麻烦的事情了(雾)。Python倒是有很多库可以实现文件的复制(我觉得,应该,大概,有的吧)但是这里就没有引入新的库了。方法如下:
import os
#测试代码
path = 'C:\Users\whats\Desktop'
def gen_file():
for i in os.listdir('.'):
yield i
def copyFile():
if not 'Copy' in os.listdir(path):
os.mkdir(path + '\Copy')
npath = 'C:\Users\whats\Desktop\Copy'
for i in gen_file():
with open(i, 'rb') as f:
content = f.read()
if not i in os.listdir(npath):
with open(npath + '\\' + i, 'wb') as f:
f.write(content)
if __name__ == '__main__':
copyFile()
以上代码只是为了测试文件允不允许被复制,如果可以复制则会被复制进入指定的文件夹=。=(注:如果文件的root中有文件夹会报错,因为只是测试嘛~)
亲测支持以下格式的复制
各种文档格式(.pdf .doc .ppt ...)
各种图片格式(.jpg .jpeg .bmp ...)
各种视频格式(.mp4 ...)
测试的文件最大为2.40GB
最后上完全体了
import os
import re
import sys
#Set Max Recursive depth
sys.setrecursionlimit(2000)
class FileCopy(object):
def __init__(self, obj_path = None, root = os.path.abspath('.')):ֵ
self.root = root
self.obj_path = obj_path
self.dirTreeList = []
def Recursive(self, path):
path = path
if os.path.isfile(path):
self.dirTreeList.append(path)
else:
L = os.listdir(path)
for i in range(len(L)):
self.Recursive(str(path) + '\\' + str(L[i]))
def Copy(self):
self.Recursive(self.root)
if not os.path.isdir(self.obj_path):
os.mkdir(self.obj_path)
while(self.dirTreeList):
count = 1
i = self.dirTreeList.pop()
name = i.split('\\')[-1]
print(name)
try:
with open(i, 'rb') as fp:
content = fp.read()
if not name in os.listdir(self.obj_path):
with open(self.obj_path + '\\'+ name, 'wb') as fp:
fp.write(content)
#Handles files with the same name
else:
with open(self.obj_path +'\\' + name, 'rb') as Exist_file:
pareContent = Exist_file.read()
if pareContent == content:
continue
else:
with open(self.obj_path + '\\'+ name + str(count), 'wb') as fp:
fp.write(content)
count += 1
except(Exception) as e:
print(e)
if __name__ == "__main__":
obj = FileCopy()
obj.Copy()
回头来看一下其实还是挺简单的,这个程序运行的速度还是有点慢,可能是因为递归的原因,本来想写个生成器对象的但是生成器递归以后返回的是生成器不知道要怎么处理,最后丢下一个未解决的问题:Python3的if有毒!!!!!!