利用python删除群晖重复文件(缓存文件MD5方式)

2023-03-20 20:48:45 26点赞 212收藏 32评论

从该文章改进:https://post.smzdm.com/p/an370emp/?zdm_ss=Android_1106136211_&send_by=1106136211&from=other&invite_code=zdmwffzv7winv

原文每次扫描都需要重新计算MD5,对于大文件来说,磁盘消耗较大,增加了缓存文件存储md5,每次扫描只计算新文件,提高效率。

修改增加比较修改时间和大小,防止文件修改后不更新md5值:

不废话,直接贴代码:

import os

import hashlib

# 只删除以下列表中的重复文件类型.如果想删除其他类型的文件,自己添加一下就行了

file_type = ['.jpg', '.jpeg', '.png', '.gif', '.psd', '.bmp', '.webp', '.mp4', '.mkv', '.avi', '.mov', 'mpeg', 'mpg',
'.rar', '.zip']
check_files = []

#自行修改目录列表
work_dir_list = [r'/volume2/111', r'/volume1/222']


class fileMd5:
def __init__(self, md5: str, st_mtime: str, len: int):
self.md5 = md5
self.st_mtime = st_mtime
self.len = len


def save_md5_file(files_dict: dict):
if files_dict is None:
return
try:
with open(md5_txt, "w") as f:
for path_md5, file_md5, in files_dict.items():
f.write(str(path_md5) + "=" + str(file_md5.md5) + ','
+ str(file_md5.st_mtime) + ','
+ str(file_md5.len) + 'n')

except Exception as e:
print(e)
pass


def open_md5_file():
files_md5 = {}
try:
with open(md5_txt, "r") as f:
for md5_line in iter(lambda: f.readline(), ""):
list_line = md5_line.split('=')
if len(list_line) != 2:
continue
list_md5 = list_line[1].split(',')
if len(list_md5) != 3:
continue
md5 = fileMd5(list_md5[0].strip(), list_md5[1].strip(), int(list_md5[2]))
files_md5[list_line[0].strip()] = md5
except Exception as e:
print(e)
pass

return files_md5


def remove_repeat_files():
for work_dir in work_dir_list:
for root, dirs, files in os.walk(work_dir):
for name in files:
p_type = os.path.splitext(os.path.join(root, name))[1]
if p_type in file_type:
check_files.append(os.path.join(root, name))
for name in dirs:
p_type = os.path.splitext(os.path.join(root, name))[1]
if p_type in file_type:
check_files.append(os.path.join(root, name))
files_dict = {}
new_files_md5 = {}
files_md5 = open_md5_file()
r_index = 0
print('Files Num:%s' % len(check_files))

for file_path in check_files:
try:
md5_path = hashlib.md5()
md5_path.update(file_path.encode('utf-8'))
path_md5 = md5_path.hexdigest()
file_md5 = files_md5.get(path_md5)
file_stats = os.stat(file_path)
st_mtime = file_stats.st_mtime
file_len = file_stats.st_size

if file_md5 is None or file_md5.st_mtime != str(st_mtime) or file_len != file_md5.len:
md5_hash = hashlib.md5()
with open(file_path, "rb+") as f:
for byte_block in iter(lambda: f.read(4096), b""):
md5_hash.update(byte_block)
file_md5 = fileMd5(str(md5_hash.hexdigest()), str(st_mtime), file_len)
print('Check file MD5:%s' % file_path)
files_md5[path_md5] = file_md5
new_files_md5[path_md5] = file_md5
if files_dict.get(file_md5.md5) is None:
files_dict[file_md5.md5] = file_path

else:
d_path = files_dict[file_md5.md5]
d_path_stats = os.stat(d_path)
d_time = d_path_stats.st_ctime
f_time = file_stats.st_ctime
if d_time > f_time:
os.remove(d_path)
files_dict[file_md5.md5] = file_path
print('Delete File:', d_path)
r_index += 1
else:
os.remove(file_path)
print('Delete File:', file_path)
r_index += 1
except Exception as e:
print(e)
pass

print('File Count:%s, Repeat Files Num:%s. All deleted!' %( len(check_files),str(r_index)))
save_md5_file(new_files_md5)


if __name__ == '__main__':
remove_repeat_files()

可以在ssh或者任务计划里执行

利用python删除群晖重复文件(缓存文件MD5方式)

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起

Synology 群晖 DS224+ 双盘位NAS(赛扬J4125、2GB)

Synology 群晖 DS224+ 双盘位NAS(赛扬J4125、2GB)

2849元起

Synology 群晖 DS220+ 2盘位NAS (赛扬J4025、2GB)

Synology 群晖 DS220+ 2盘位NAS (赛扬J4025、2GB)

2179元起

Synology 群晖 DS920+ 4盘位 NAS存储(J4125、4GB)

Synology 群晖 DS920+ 4盘位 NAS存储(J4125、4GB)

2190.84元起

Synology 群晖 DS423+ 4盘位 NAS网络存储 (Intel四核 、无内置硬盘)

Synology 群晖 DS423+ 4盘位 NAS网络存储 (Intel四核 、无内置硬盘)

4099元起

Synology 群晖 DS1821+ 8盘位NAS (V1500B、4GB)

Synology 群晖 DS1821+ 8盘位NAS (V1500B、4GB)

8899元起

Synology 群晖 DS223j 双盘位 NAS网络存储服务器 私有云 智能相册 文件自动同步

Synology 群晖 DS223j 双盘位 NAS网络存储服务器 私有云 智能相册 文件自动同步

1549元起

Synology 群晖 DS923+ NAS网络存储服务器 标准无硬盘

Synology 群晖 DS923+ NAS网络存储服务器 标准无硬盘

4899元起

Synology 群晖 DS1821+ 8盘位 NAS(V1500B、4GB)

Synology 群晖 DS1821+ 8盘位 NAS(V1500B、4GB)

7196元起

Synology 群晖 DS720+ 双盘位NAS(J4125、2GB)

Synology 群晖 DS720+ 双盘位NAS(J4125、2GB)

4099元起

群晖(Synology)DS124单盘位NAS网络存储服务器私有云智能相册文件自动同步

群晖(Synology)DS124单盘位NAS网络存储服务器私有云智能相册文件自动同步

1399元起

Synology 群晖 DS218+ 2盘位 NAS网络存储服务器 京东云定制版(J3355、2GB)

Synology 群晖 DS218+ 2盘位 NAS网络存储服务器 京东云定制版(J3355、2GB)

暂无报价

synology群晖nas云存储ds920+中小型企业办公网络存储群辉家庭个人私有云盘四盘位NAS备份硬盘服务器ds918+(DS920+希捷企业级16T*4)

synology群晖nas云存储ds920+中小型企业办公网络存储群辉家庭个人私有云盘四盘位NAS备份硬盘服务器ds918+(DS920+希捷企业级16T*4)

13746元起

Synology 群晖 DS416 企业级 NAS网络存储

Synology 群晖 DS416 企业级 NAS网络存储

暂无报价

Synology 群晖 DS420+ 4盘位NAS (赛扬J4025、2GB)

Synology 群晖 DS420+ 4盘位NAS (赛扬J4025、2GB)

3090元起

Synology 群晖 DS423 四核心 4盘位 NAS网络存储 私有云 照片自动备份

Synology 群晖 DS423 四核心 4盘位 NAS网络存储 私有云 照片自动备份

3199元起

Synology 群晖 DS223 2盘位NAS(Realtek RTD1619B、2GB)

Synology 群晖 DS223 2盘位NAS(Realtek RTD1619B、2GB)

2299元起
32评论

  • 精彩
  • 最新
  • 大佬,其他品牌的NAS代码能用吗?

    校验提示文案

    提交
    pc上都可以用,但是要注意权限,md5.txt要生成在有写入权限的地方

    校验提示文案

    提交
    收起所有回复
  • 提问:因为我的群晖是多人协作的, 有多人的目录,里面确实有很大量的重复内容,那这个删除后,是其他人的目录下的文件直接就消失了嘛,还是直接改了指向的意思 [喜极而泣] ,有这么高级嘛 [喜极而泣]

    校验提示文案

    提交
    这个只是删文件,你要是查重用链接的方式需要妥善的方案,例如将重复文件放到公共目录里,其他的目录创建一个链接,再高级的功能你可能需要一个云存储来做了,不然过于复杂可能维护会出问题

    校验提示文案

    提交
    感谢回复,确实商用的群晖,同事各自有自己的目录,其实50%以上的文件都是重复的,尤其是公司资质、项目介绍啥的,但一直没有比较好的办法去去重处理这个浪费。我甚至把这个需求提给官方过,当然必然没有解决。。。哈,“将重复文件放到公共目录里,其他的目录创建一个链接”如果真的实现,那真的是解决大麻烦了

    校验提示文案

    提交
    还有2条回复
    收起所有回复
  • MD5并不唯一,且用且珍惜

    校验提示文案

    提交
    碰撞的概率很低的,如果怕撞,还可以用sha,长度比对,就是效率下降不少

    校验提示文案

    提交
    收起所有回复
  • 谢谢大佬,可以删除成功。但是出现两个报错 1,好多@eaDir下文件回报错“[Errno 21] Is a directory: '/volume2/homes/wzz/Drive/Moments/20080313/@eaDir/20100221002.jpg'”2,最后结束的时候会报错“File Count:24856, Repeat Files Num:31. All deleted!
    name 'md5_txt' is not defined” 说md5_txt没有定义,是哪里的问题呢

    校验提示文案

    提交
    还有一开始也有个报错 f'spec_for_{name}',
    ^
    SyntaxError: invalid syntax

    校验提示文案

    提交
    删除for name in dirs:
    p_type = os.path.splitext(os.path.join(root, name))[1]
    if p_type in file_type:
    check_files.append(os.path.join(root, name)),md5_txt已经定义一下路径

    校验提示文案

    提交
    收起所有回复
  • 一开始我也是这样想,后面我绕开了这个思路。首先用文件大小分组,然后再用moviepy获取视频文件信息,用文件时间、文件类型、文件分辨率等多层级分组,最后剩下的就是重复文件,然后硬连接去重了。
    个人测试没问题,即使有问题了,根据文件名大不了重新下载呗。

    校验提示文案

    提交
    硬连接不是所有文件系统支持的,有限制的,能支持也是一个不错的方法,反正思路都是一样的

    校验提示文案

    提交
    主要是你用md5或者sha去计算读文件,文件多了占用cpu太多了,我的j3455直接卡死,没办法。。。

    校验提示文案

    提交
    还有1条回复
    收起所有回复
  • /bin/bash: Python3: command not found 报错

    校验提示文案

    提交
    把python3改成python ,还不行就是没装python运行时,安装一下就好了

    校验提示文案

    提交
    运行命令开头大写了 没看出来 [喜极而泣] [喜极而泣]

    校验提示文案

    提交
    收起所有回复
  • 以前也想过 但是碰到一个自动删除文件时的选择问题就放弃了。后来选择手动了。例如A目录下有一个系列1、2、3、4的jpg旅游照片。然后各种情况 A/a目录下有4 ,或者 c目录下 也有3这一个相同的文件。最后自动删除就变成A目录125文件, A/a下4,C下3。文件变得割裂了。

    校验提示文案

    提交
    这个可以用符号链接解决

    校验提示文案

    提交
    硬链接吗? 不过这样的感觉文件整理上没有达到想要的效果。虽然文件占用上解决了。但是当第三方应用 例如倒入整个目录下的图片 展示时。 又会导入不同路径下,相同内容的图片或者视频。

    校验提示文案

    提交
    收起所有回复
  • 好思路!

    校验提示文案

    提交
  • 其实群晖有存储空间分析器

    校验提示文案

    提交
    那个只能告诉你有重复文件,不会主动利用btrfs文件系统的特性在保留所有文件的基础上只占用一份文件的空间。

    校验提示文案

    提交
    额,如果你是群晖操作,设置有个文件快速克隆,而且我说的是这个删除没必要,开下报告,自己赛选下更安全点

    校验提示文案

    提交
    还有2条回复
    收起所有回复
  • 大佬

    校验提示文案

    提交
  • 硬核

    校验提示文案

    提交
  • 太硬核了

    校验提示文案

    提交
  • 为什么python不缩进啊????

    校验提示文案

    提交
提示信息

取消
确认
评论举报

相关好价推荐
查看更多好价

相关文章推荐

更多精彩文章
更多精彩文章

siseniao

Ta还没有介绍自己

关注 打赏
最新文章 热门文章
212
扫一下,分享更方便,购买更轻松