You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程查找重复文件及Android手机全机重复文件查找方法

问题1:编程实现重复文件查找的方案

核心逻辑是分层筛选,尽可能降低不必要的哈希计算量,提升扫描效率:

  • 第一步:遍历目标目录下的所有文件,过滤目录、符号链接等非普通文件对象,记录所有文件的路径、大小信息
  • 第二步:按文件大小分组,只有文件大小完全一致的才可能是重复文件,直接排除大小不同的文件,可降低90%以上的后续计算量
  • 第三步:对同大小分组内的文件,先计算文件前16KB的哈希值(MD5或SHA-256均可),再次分组,排除前16KB哈希不同的文件
  • 第四步:对剩余的同大小、同前16KB哈希的文件,计算全文件哈希值,哈希值完全相同的判定为重复文件

示例Python核心代码如下:

import os
import hashlib

def get_file_hash(file_path, block_size=65536, partial=False):
    hash_obj = hashlib.sha256()
    with open(file_path, 'rb') as f:
        while True:
            block = f.read(block_size)
            if not block:
                break
            hash_obj.update(block)
            if partial: # 仅读取前一块用于快速筛选
                break
    return hash_obj.hexdigest()

def find_duplicates(root_path):
    size_map = {}
    # 第一步:按文件大小分组
    for root, _, files in os.walk(root_path):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                file_size = os.path.getsize(file_path)
            except OSError:
                continue
            if file_size not in size_map:
                size_map[file_size] = []
            size_map[file_size].append(file_path)
    # 过滤只有一个文件的大小组
    size_map = {k:v for k,v in size_map.items() if len(v)>=2}
    dup_groups = []
    for file_list in size_map.values():
        # 第二步:按前16KB哈希分组
        partial_hash_map = {}
        for fp in file_list:
            try:
                p_hash = get_file_hash(fp, partial=True)
            except OSError:
                continue
            if p_hash not in partial_hash_map:
                partial_hash_map[p_hash] = []
            partial_hash_map[p_hash].append(fp)
        partial_hash_map = {k:v for k,v in partial_hash_map.items() if len(v)>=2}
        # 第三步:按全文件哈希分组
        for plist in partial_hash_map.values():
            full_hash_map = {}
            for fp in plist:
                try:
                    f_hash = get_file_hash(fp)
                except OSError:
                    continue
                if f_hash not in full_hash_map:
                    full_hash_map[f_hash] = []
                full_hash_map[f_hash].append(fp)
            dup_groups.extend([v for v in full_hash_map.values() if len(v)>=2])
    return dup_groups

额外注意事项:

  • 大于4GB的大文件可以随机抽取多块位置的哈希做校验,不需要全量计算,大幅降低资源消耗
  • 扫描过程要跳过系统锁文件、无权限访问的文件,避免程序崩溃
问题2:Android整机存储重复文件扫描方案

分两种权限场景实现:

无需Root的方案

  • 先申请对应存储权限:Android 13及以上需要申请READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO权限;Android 12及以下需要申请READ_EXTERNAL_STORAGE权限;如果要扫描所有类型的文件需要申请MANAGE_EXTERNAL_STORAGE权限,需引导用户到系统设置页手动开启
  • 优先通过MediaStore接口查询所有公共存储文件的路径、大小信息,比直接遍历文件系统速度快3~5倍,Kotlin示例查询代码:
val projection = arrayOf(MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.SIZE)
val cursor = contentResolver.query(MediaStore.Files.getContentUri("external"), projection, null, null, null)
cursor?.use {
    val dataIndex = it.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)
    val sizeIndex = it.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)
    while (it.moveToNext()) {
        val filePath = it.getString(dataIndex)
        val fileSize = it.getLong(sizeIndex)
        // 存入大小分组做后续筛选
    }
}
  • 后续判定重复文件的逻辑和上面的编程实现逻辑完全一致,扫描完成后可按图片、视频、文档、安装包等分类展示重复文件,供用户选择清理

已Root的方案

  • 获取根目录读写权限后,直接遍历/根目录下的所有分区(包括系统分区、内置存储、外置SD卡等),复用相同的哈希校验逻辑扫描即可,注意不要随意删除系统分区的重复文件,避免系统运行异常

内容的提问来源于stack exchange,提问作者Thoriya Prahalad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:09:02