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
# 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多分钟,支持大数据量,如果有什么不懂的,可以邮件联系我或者等待我的评论系统搞完,over
github地址在这: https://github.com/Alexanderklau/Amusing_python/tree/master/File_operation/repeat
Python高效率遍历文件夹寻找重复文件的更多相关文章
- python遍历文件夹中所有文件夹和文件,os.walk
python中可以用os.walk来遍历某个文件夹中所有文件夹和文件. 例1: import os filePath = 'C:/Users/admin/Desktop/img' for dirpat ...
- python (9)统计文件夹下的所有文件夹数目、统计文件夹下所有文件数目、遍历文件夹下的文件
命令:os 用到的:os.walk os.listdir 写的爬虫爬的数据,但是又不知道进行到哪了,于是就写了个脚本来统计文件的个数 #统计 /home/dir/ 下的文件夹个数 import o ...
- python 遍历文件夹中所有文件
'''使用walk方法递归遍历目录文件,walk方法会返回一个三元组,分别是root.dirs和files. 其中root是当前正在遍历的目录路径:dirs是一个列表,包含当前正在遍历的目录下所有的子 ...
- 10行Python代码自动清理电脑内重复文件,解放双手!
大家好,又到了Python办公自动化系列. 今天分享一个系统层面的自动化案例: 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做 ...
- python 实现彻底删除文件夹和文件夹下的文件
python 中有很多内置库可以帮忙用来删除文件夹和文件,当面对要删除多个非空文件夹,并且目录层次大于3层以上时,仅使用一种内置方法是无法达到彻底删除文件夹和文件的效果的,比较low的方式是多次调用直 ...
- Python列出文件夹中的文件
几乎所有的关于操作系统的内容可以在python 官方文档中找到:https://docs.python.org/3/library/os.html#module-os 其中os.path被单独列出:h ...
- C#遍历文件夹下所有文件
FolderForm.cs的代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using ...
- PHP遍历文件夹下的文件和获取到input name的值
<?php$dir = dirname(__FILE__); //要遍历的目录名字 ->当前文件所在的文件夹//$dir='D:\PHP\wamp\www\admin\hosts\admi ...
- c# 遍历文件夹及其所有文件
利用VS创建一个winform应用程序,遍历指定文件夹(photos)内的所有文件夹及其文件.具体程序如下: namespace 遍历文件夹及其所有文件 { public partial class ...
随机推荐
- a ^ b mod c 取模运算优化反思(老物)
这是一篇嘲讽我之前的自己采用笨重愚蠢思想去解决问题的日志. RSA 加密与解密涉及到 a ^ b mod c 的问题,如何计算这个值呢? 我会选择 pow(a, b) % c, 事实上在写RSA的时候 ...
- vue中使用better-scroll滚动条插件
应用场景: overflow: hidden会让超出的部分隐藏,并且无法拖拽,所以可使用插件让长列表限定的区域滚动拖拽. 参考:https://zhuanlan.zhihu.com/p/2740702 ...
- 微信公众号接口类(PHP版本)
[项目需求] 通过微信提供的接口,实现微信公众号与后端的应用程序数据交互.消息响应等功能. [项目疑难点] 理解接口工作方式,统一接口API,响应速度.安全性等 [代码举例] WeixinAp ...
- Halcon WPF C#采集图像区域灰度值
源码下载地址:https://github.com/lizhiqiang0204/ImageGray.git Halcon代码如下: *读取图片,转换成灰度图片 read_image (Image1, ...
- VMmare下安装redhat
一.虚拟机必须安装在自定义的文件夹下,虚拟硬盘文件必须存放在自定义路径下(避免中文) 二.安装时选择linux类型时必须选择red hat enterprise linux 5 64位 三.操作系统名 ...
- ViewContainerRef 动态创建视图
Angular DOM 操作 相关的APIs和类: 查询DOM节点 template variable ref: 模版变量引用,相当于react中的ref ViewChild: 查询DOM,返回单个元 ...
- [USACO07OPEN]Dining 题解
前言 如果有人不会网络流,那么安利一下我网络最大流Dinic的博客 关于网络流,我多久没有碰这个算法了... 这是一道网络流好题. 题解 这道题目难点主要是构图. 这道题的构图一开始很容易想到建一个超 ...
- Android内嵌网页webview点击其中的链接跳转到我们应用内的Activity
在一个大的Android项目中,由于客户端来不及更新和实现,经常会内嵌一些网页(在一些大型的互联网公司,PC的产品总是跑在客户端的前面),比如活动页面,通常可以内嵌用html5实现的页面,可以适配手机 ...
- Java 统计单词频数
输出单个文件中的 N 个英语单词出现的次数 定义双列集合,将单词不重复的读入一列中,另一列用来计数 import java.io.BufferedReader; import java.util.Ar ...
- Linux下" >/dev/null 2>&1 "详解
在学习Linux的过程中,常会看到一些终端命令或者程序中有">/dev/null 2>&1 "出现,由于已经遇到了好几次了,为了理解清楚,不妨花点时间百度或者g ...