当前位置:
首页 > temp > python入门教程 >
-
Python教程:高效率遍历文件夹寻找重复文件
前言
为什么要写这篇文章呢。。。主要还是业务中有个需求,遍历一个将近200w数据的文件夹,大部分还都是视频文件那种,但是这玩意用的次数还不多,做文件夹index也不是很ok,所以写了一个脚本来处理这个问题,从而发现了自己的一些薄弱点,将其记录下来,方便自己,也方便未来其他的兄弟使用
基本需求
- 把文件夹中的重复文件找出来
- 找出来之后用csv输出,左边是源文件,右边是重复文件
- 效率不能差,不能直接撑爆内存,不能占用过多资源
- 检测的文件夹和存放csv的地方可以自己定义,加上终端交互
- 重复文件筛选支持md5,大小等方式
需求分析
首先要分析一点,就是我们该如何去做重复文件的对比,并且效率还要高,首先网上过多的递归,os.walk的方法不可用,因为他们都会把遍历到的内容直接做成一个大列表,塞到内存里面,数据量大很容易爆掉,并且还要进行MD5,或者是大小比对,这个就非常难缠了。
基础想法
其实说白了,拿到所有文件列表file_list,把文件依次对比,这里我们可以用dict,分两种情况
按照文件名和大小
设定两个dict,例如record和dup,遍历file_list,生成一个数组,比对其中的文件名和大小
按照大小和MD5值
设定两个dict,例如record和dup,遍历file_list,生成一个数组,比对其中的md5值和大小
具体代码
闲话休提,我们开始写代码吧
定义遍历函数代码
首先定义遍历文件夹的部分diskwalk.py
# coding: utf-8
__author__ = "lau.wenbo"
import os,sys
class diskwalk(object):
def __init__(self, path):
self.path = path
def paths(self):
path = self.path
# 这里用了一个迭代器逻辑,防止所有数据塞内存爆掉
path_collection = (os.path.join(root,fn) for root,dirs,files in os.walk(path) for fn in files)
return path_collection
定义检查md5值代码
接着我们定义检查md5值的一个逻辑checksum.py
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# coding: utf-8
__author__ = "lau.wenbo"
import hashlib,sys
# 分块读MD,速度快
def create_checksum(path):
fp = open(path)
checksum = hashlib.md5()
while True:
buffer = fp.read(8192)
if not buffer: break
checksum.update(buffer)
fp.close()
checksum = checksum.digest()
return checksum
定义主函数代码
# coding: utf-8
__author__ = "lau.wenbo"
from checksum import create_checksum
from diskwalk import diskwalk
from os.path import getsize
import csv
import os
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def findDupes(path):
record = {}
dup = {}
d = diskwalk(path)
files = d.paths()
for file in files:
try:
# 这里使用了大小,文件名的对比方式,如果你需要MD5值的对比方式,可以打开下面的注释
#compound_key = (getsize(file),create_checksum(file))
compound_key = (getsize(file), file.split("/")[-1])
if compound_key in record:
dup[file] = record[compound_key]
else:
record[compound_key]=file
except:
continue
return dup
if __name__ == '__main__':
path = sys.argv[1]
csv_path = sys.argv[2]
if not os.path.isdir(path) or not os.path.isdir(csv_path) or csv_path[-1] != "/":
print u"参数不是一个有效的文件夹!"
exit()
else:
path = path.decode("utf-8")
print u"待检测的文件夹为{path}".format(path=path)
with open(u"{csv_path}重复文件.csv".format(csv_path=csv_path),"w+") as csvfile:
# 源文件 重复文件
header = ["Source", "Duplicate"]
writer = csv.DictWriter(csvfile, fieldnames=header)
writer.writeheader()
print u"开始遍历文件夹,寻找重复文件,请等待........."
print u"开始写入CSV文件,请等待........"
for file in findDupes(path).items():
writer.writerow({"Source":file[1],"Duplicate":file[0]})
结语
实现了哪些功能呢,哈哈,结尾来说一下,其实核心就是我用了一个列表生成器,加了一个迭代器,迭代器可是好东西,不会撑内存,不错了,效率也还可以,200w数据判定也就20多分钟,支持大数据量
出处:https://www.cnblogs.com/djdjdj123/p/13633548.html
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数