前言

为什么要写这篇文章呢。。。主要还是业务中有个需求,遍历一个将近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. vue.js table组件封装

    table组件 和 分页组件来自iview,在这里我根据公司业务再次做了一次封装,使用slot进行内容分发,可以随意放置input输入框和button按钮 ,再使用props向子组件传递参数,使用em ...

  2. Laplace's equation

    链接:https://en.wikipedia.org/wiki/Laplace%27s_equation

  3. 写了一个简单的 Mybatis

    写了一个简单的 Mybatis,取名 SimpleMybatis . 具备增删改查的基本功能,后续还要添加剩下的基本数据类型和Java集合类型的处理. 脑图中有完整的源码和测试的地址 http://n ...

  4. MongoDB的安装以及启动

    1.首先什么是MongoDB? MongoDB是一个基于分布式文件存储的数据库,是由c++语言编写的.为web应用提供可扩展的高性能数据的存储方案.是一个介于关系型数据库和非关系型数据库 的中间产品, ...

  5. Chrome设置--disable-web-security解决跨域问题

    这里介绍的是--disable-web-security参数.这个参数可以降低chrome浏览器的安全性,禁用同源策略,利于开发人员本地调试. (1)新建一个chrome快捷方式,右键“属性”,“快捷 ...

  6. 解决git 命令出现end问题

    当使用git branch -r是当分支有很多的时候出现end 使用:q可以退出

  7. linux运维、架构之路-MySQL日志(三)

    一.MySQL日志 1.错误日志 ①配置方法 [mysqld] log-error=/data/mysql/mysql.log ②查看配置方式 mysql> show variables lik ...

  8. 内核热patch

    如下代码是一个内核patch #include <linux/init.h> #include <linux/module.h> #include <linux/modu ...

  9. 数组Array方法: indexOf、filter、forEach、map、reduce使用实例

  10. CSS盒子模型中的Padding属性

    CSS padding 属性 CSS padding 属性定义元素边框与元素内容之间的空白区域,不可见.如果想调整盒子的大小可以调整内容区,内边距,边框. CSS padding 属性定义元素的内边距 ...