前言

为什么要写这篇文章呢。。。主要还是业务中有个需求,遍历一个将近200w数据的文件夹,大部分还都是视频文件那种,但是这玩意用的次数还不多,做文件夹index也不是很ok,所以写了一个脚本来处理这个问题,从而发现了自己的一些薄弱点,将其记录下来,方便自己,也方便未来其他的兄弟使用

基本需求

  1. 把文件夹中的重复文件找出来
  2. 找出来之后用csv输出,左边是源文件,右边是重复文件
  3. 效率不能差,不能直接撑爆内存,不能占用过多资源
  4. 检测的文件夹和存放csv的地方可以自己定义,加上终端交互
  5. 重复文件筛选支持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高效率遍历文件夹寻找重复文件的更多相关文章

  1. python遍历文件夹中所有文件夹和文件,os.walk

    python中可以用os.walk来遍历某个文件夹中所有文件夹和文件. 例1: import os filePath = 'C:/Users/admin/Desktop/img' for dirpat ...

  2. python (9)统计文件夹下的所有文件夹数目、统计文件夹下所有文件数目、遍历文件夹下的文件

    命令:os 用到的:os.walk   os.listdir 写的爬虫爬的数据,但是又不知道进行到哪了,于是就写了个脚本来统计文件的个数 #统计 /home/dir/ 下的文件夹个数 import o ...

  3. python 遍历文件夹中所有文件

    '''使用walk方法递归遍历目录文件,walk方法会返回一个三元组,分别是root.dirs和files. 其中root是当前正在遍历的目录路径:dirs是一个列表,包含当前正在遍历的目录下所有的子 ...

  4. 10行Python代码自动清理电脑内重复文件,解放双手!

    大家好,又到了Python办公自动化系列. 今天分享一个系统层面的自动化案例: 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做 ...

  5. python 实现彻底删除文件夹和文件夹下的文件

    python 中有很多内置库可以帮忙用来删除文件夹和文件,当面对要删除多个非空文件夹,并且目录层次大于3层以上时,仅使用一种内置方法是无法达到彻底删除文件夹和文件的效果的,比较low的方式是多次调用直 ...

  6. Python列出文件夹中的文件

    几乎所有的关于操作系统的内容可以在python 官方文档中找到:https://docs.python.org/3/library/os.html#module-os 其中os.path被单独列出:h ...

  7. C#遍历文件夹下所有文件

    FolderForm.cs的代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using ...

  8. PHP遍历文件夹下的文件和获取到input name的值

    <?php$dir = dirname(__FILE__); //要遍历的目录名字 ->当前文件所在的文件夹//$dir='D:\PHP\wamp\www\admin\hosts\admi ...

  9. c# 遍历文件夹及其所有文件

    利用VS创建一个winform应用程序,遍历指定文件夹(photos)内的所有文件夹及其文件.具体程序如下: namespace 遍历文件夹及其所有文件 { public partial class ...

随机推荐

  1. WindowsForms使用Telerik Reporting

    新建一个WindowsForms窗体项目 然后拖动ReportViewer这个控件到WindowsForms的窗体中 如上图所示,用来呈现报表的控件,这个控件可以打印报表,转换报表这类的功能 接下来我 ...

  2. 自己制作 Android Vector Asset 矢量图

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/c5138891/article/deta ...

  3. 关于Mysql select语句中拼接字符串的记录

    在mysql的SELECT语句中拼接两列(或多列)的字符串显示: mysql> select concat(dname,loc) from dept; 以上语句便把dept表的dname,loc ...

  4. 第三次作业—Wordcount

    一.地址 Github项目地址:https://github.com/1320068008/WordCount-1 同伴蒋鑫作业地址:https://www.cnblogs.com/JxsBK/p/1 ...

  5. 字符串与List互转

    List转字符串,用逗号隔开 List<string> list = new List<string>(); list.Add("a"); list.Add ...

  6. Centos7.5 rpm安装zabbix_agent4.0.3

    1.下载并且安装 cd /data/tools/ ##切换到下载客户端目录 wget http://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-ag ...

  7. 带加载进度的Web图片懒加载组件Lazyload

    在Web项目中,大量的图片应用会导致页面加载时间过长,浪费不必要的带宽成本,还会影响用户浏览体验. Lazyload 是一个文件大小仅4kb的图片懒加载组件(不依赖其它第三方库),组件会根据用户当前浏 ...

  8. 在目标端重建sequence的脚本

    select 'create sequence '||SEQUENCE_OWNER||'.'||sequence_name|| ' minvalue '||min_value|| ' maxvalue ...

  9. CF547E Mike and Friends

    子串看起来就很SuffixStructures 于是上SAM 本来想着直接LCT 后来发现没法串定位(暴力匹配复杂度不对) 然后就离线吧,先建出来然后链加子树和,树剖就odk. 其实更直接的套路是线段 ...

  10. [Comet OJ - Contest #9 & X Round 3] Namid[A]me

    传送门 一开始读错题了,以为是\(\sum_{1\leq u\leq v\leq n}f(u,v)\),还疑惑这题这么简单怎么没人做( 实际上是\(\sum_{1\leq u\leq v\leq n} ...