找回密码
 加入
搜索
查看: 2679|回复: 12

[系统综合] AU3如何判断两个文件是否重复?[已解决]

  [复制链接]
发表于 2017-9-23 10:55:11 | 显示全部楼层 |阅读模式
本帖最后由 cashiba 于 2017-9-26 17:25 编辑

两个同样的文件,或文件名不同,或创建时间不同,或一些其它外在属性不同.....
用AU3如何判断呢?
搜了一下,好像类似的帖子很少....

对文件的内在结构不懂,度了一下,说内容相同的文件其文件头文件尾的数据可能会有不同,还有MD5、hash值什么的相同可判断文件相同。

找到一段python语言的写的重复文件判断代码,但是不懂python,基本上看不懂,哪位大侠能将其转为AU3呢?
#!/usr/bin/env python
#coding=utf-8
'''
Created on Nov 30, 2016

@author: fangcheng
'''
from __future__ import print_function
from operator import itemgetter  
import os
import time

'tt为浮点型日期,换化为年月日时分秒格式时间'
def timeYS(tt):
    t1 = time.localtime(tt)
    t2 = time.strftime("%Y-%m-%d %H:%M:%S",t1)
    return t2;  
        
class File():
    '''
    copy move remove
    '''
    allfilecount = 0
    rddfilecount = 0
    singlefiles={}
    rddfiles={}
    rdddirs={}

    def __init__(self):
        '''
        Constructor
        '''
    def getFileMsg(self,filepath):
        '''
        以元组(filepath,ftime,size)形式输出文件信息
        '''
        if os.path.isfile(filepath):
            size = os.path.getsize(filepath)  #bytes B 
            if size <= 1024:
                size ='{0}B'.format(size);
            elif size <= 1024*1024:
                size = size/1024
                size ='{0}K'.format(size);
            else:
                size = size/1024/1024
                size ='{0}M'.format(size);
            #filename = os.path.basename(filepath)
            
            ftime = timeYS(os.path.getmtime(filepath))
            return (filepath,ftime,size)
        return ()
    
    
    
    def setRedundanceFile(self,filepath):
        '''
        根据文件名称和大小判断文件是否重复,文件信息:元组(filepath,mtime,size) ,getFileMsg返回值
        1. 遍历某一目录下所有文件
        2. 将文件的名称及大小组成一个字符串,做为 key 放入字典 dict1 ,其 value 为 文件信息
        3. 每次放入时时判断 key 是否存在,若存在,就将 文件信息 放入字典 dict2
        4. dict2 的 key 为 文件名称,value为 文件信息 列表 list1
        '''
        try:
            if os.path.isdir(filepath):
                for fil in os.listdir(filepath):
                    fil = os.path.join(filepath,fil)
                    self.setRedundanceFile(fil)
            elif os.path.isfile(filepath):
                self.allfilecount = self.allfilecount + 1
                size = os.path.getsize(filepath)  
                filename = os.path.basename(filepath)
                f = self.getFileMsg(filepath)

                filekey = '{0}_{1}'.format(filename, size)
                
                if self.singlefiles.has_key(filekey):
                    self.rddfilecount = self.rddfilecount + 1
                    
                    #增加规则:发现一个重复文件时,在父目录下文件数加1,若是首次发现则取该文件在总文件列表的父目录,其数目也加1
                    pardir = os.path.dirname(filepath)
                    if self.rdddirs.has_key(pardir):
                        self.rdddirs[pardir] = self.rdddirs.get(pardir)+1
                    else:
                        self.rdddirs[pardir] = 1
                    
                    
                    if self.rddfiles.has_key(filekey) :
                        self.rddfiles[filekey].append(f)
                    else:
                        self.rddfiles[filekey] = [f]
                        f = self.singlefiles.get(filekey)
                        self.rddfiles[filekey].append(f)
                        #若是首次发现则取该文件在总文件列表的父目录,其数目也加1
                        pardir = os.path.dirname(f[0])
                        if self.rdddirs.has_key(pardir):
                            self.rdddirs[pardir] = self.rdddirs.get(pardir)+1
                        else:
                            self.rdddirs[pardir] = 1
                        
                        
                else:
                    self.singlefiles[filekey]=f
                    
            else:
                return
                    
        except Exception as e:
            print(e)
        
    
    def showFileCount(self):
        print(self.allfilecount)
    
    def showRedundanceFile(self,filepath):
        '''
        根据文件名称和大小判断文件是否重复
        '''
        self.allfilecount = 0
        self.rddfilecount = 0
        self.singlefiles={}
        self.rddfiles={}
        
        
        
        self.setRedundanceFile(filepath)
        print('the total file num:{0},the redundance file num(not including the first file):{1}'.format(self.allfilecount,self.rddfilecount))
        print('-----------------------------------------')
        for k in self.rddfiles.keys():
            for l in sorted(self.rddfiles.get(k), key=itemgetter(1)): #按修改日期升序排列
                print(l);
            print('');
        print('------------------------------------------')
        
        
        
    def showCanRemoveFile(self,filepath):
        '''
        根据文件名称和大小判断文件是否重复
        输出按修改时间较旧的文件
        '''
        self.allfilecount = 0
        self.rddfilecount = 0
        self.singlefiles={}
        self.rddfiles={}
        rmlist = []
        self.setRedundanceFile(filepath)
        
        for k in self.rddfiles.keys():
            tmplist = sorted(self.rddfiles.get(k), key=itemgetter(1))
            tmplist.pop()
            rmlist.extend(tmplist)
        for rl in rmlist:
            print(rl[0])
        
    def rdddirstat(self):  
        '''
        按目录统计文件重复个数
        输出:目录/tmp  重复个数5,是指/tmp目录下有5个文件在其他地方也存在
        
        '''
        if len(self.rdddirs)> 0 :
            print('The redundance file statistics by dirs:')
            for rd in self.rdddirs.keys():
                print('{0} {1}'.format(rd, self.rdddirs.get(rd)))
        else:
            print('There are no redundance files')
        
if __name__ == '__main__':
    f = File()
    filepath = os.getcwd()
    #filepath = '/scripts'
    
    f.showRedundanceFile(filepath) #查看多余的文件
    #f.showCanRemoveFile(filepath)  #按修改时间给出比较旧的多余文件
    f.rdddirstat()                 #按目录统计重复文件个数
发表于 2017-9-23 16:03:08 | 显示全部楼层
用md5判断最普遍,,一般都是用这个。。
 楼主| 发表于 2017-9-23 18:50:08 | 显示全部楼层
怎么判断呢?只找到FileGetAttrib,获取文件外部属性的....
文件的MD5或hash或 sha1用什么函数获取呢?
发表于 2017-9-23 19:28:16 | 显示全部楼层
md5最快,有重复再检测其他。
上面的python代码的用的是判断文件属性里的信息
发表于 2017-9-23 19:49:48 | 显示全部楼层
回复 3# cashiba


    帮助文件中搜索
_Crypt_HashFile

评分

参与人数 1金钱 +20 收起 理由
cashiba + 20 谢谢指点...

查看全部评分

发表于 2017-9-23 19:57:45 | 显示全部楼层
左边是haozip自带的md5计算。。右边是我高仿的au3版

基本上,就是楼上那个函数的作用了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2017-9-24 15:44:49 | 显示全部楼层
可以用Beyond Compare
 楼主| 发表于 2017-9-24 22:36:03 | 显示全部楼层
回复  cashiba
_Crypt_HashFile
yamakawa 发表于 2017-9-23 19:49

原来_Crypt_HashFile函数就是做这个用的,以前看到这个函数不太懂......
那个CRC32值是怎么算来的呢?找到
_WinAPI_ComputeCrc32
计算内存块的 CRC32 校验和.
看不懂。
 楼主| 发表于 2017-9-24 22:41:03 | 显示全部楼层
可以用Beyond Compare
zzwwdd 发表于 2017-9-24 15:44

用第三方工具有时不如用自己做的小巧随意....
发表于 2017-9-25 14:39:44 | 显示全部楼层
MD5值对比一波  来的快一点吧。
发表于 2017-9-25 20:05:30 | 显示全部楼层
回复 8# cashiba


    我用的是这个。。。忘记是什么地方收集来的。。
; #FUNCTION# ;===============================================================================
;
; Name...........: _CRC32ForFile
; Description ...: Calculates CRC32 value for the specific file.
; Syntax.........: _CRC32ForFile ($sFile)
; Parameters ....: $sFile - Full path to the file to process.
; Return values .: Success - Returns CRC32 value in form of hex string
;                          - Sets @error to 0
;                  Failure - Returns empty string and sets @error:
;                  |1 - CreateFile function or call to it failed.
;                  |2 - CreateFileMapping function or call to it failed.
;                  |3 - MapViewOfFile function or call to it failed.
;                  |4 - RtlComputeCrc32 function or call to it failed.
; Author ........: trancexx
;
;==========================================================================================
Func _CRC32ForFile($sFile)

        Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFileW", _
                        "wstr", $sFile, _
                        "dword", 0x80000000, _ ; GENERIC_READ
                        "dword", 3, _ ; FILE_SHARE_READ|FILE_SHARE_WRITE
                        "ptr", 0, _
                        "dword", 3, _ ; OPEN_EXISTING
                        "dword", 0, _ ; SECURITY_ANONYMOUS
                        "ptr", 0)

        If @error Or $a_hCall[0] = -1 Then
                Return SetError(1, 0, "")
        EndIf

        Local $hFile = $a_hCall[0]

        $a_hCall = DllCall("kernel32.dll", "ptr", "CreateFileMappingW", _
                        "hwnd", $hFile, _
                        "dword", 0, _ ; default security descriptor
                        "dword", 2, _ ; PAGE_READONLY
                        "dword", 0, _
                        "dword", 0, _
                        "ptr", 0)

        If @error Or Not $a_hCall[0] Then
                DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
                Return SetError(2, 0, "")
        EndIf

        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)

        Local $hFileMappingObject = $a_hCall[0]

        $a_hCall = DllCall("kernel32.dll", "ptr", "MapViewOfFile", _
                        "hwnd", $hFileMappingObject, _
                        "dword", 4, _ ; FILE_MAP_READ
                        "dword", 0, _
                        "dword", 0, _
                        "dword", 0)

        If @error Or Not $a_hCall[0] Then
                DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
                Return SetError(3, 0, "")
        EndIf

        Local $pFile = $a_hCall[0]
        Local $iBufferSize = FileGetSize($sFile)

        Local $a_iCall = DllCall("ntdll.dll", "dword", "RtlComputeCrc32", _
                        "dword", 0, _
                        "ptr", $pFile, _
                        "int", $iBufferSize)

        If @error Or Not $a_iCall[0] Then
                DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
                DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
                Return SetError(4, 0, "")
        EndIf

        DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)

        Local $iCRC32 = $a_iCall[0]

        Return SetError(0, 0, Hex($iCRC32))

EndFunc   ;==>_CRC32ForFile

评分

参与人数 1金钱 +20 收起 理由
cashiba + 20 谢谢...

查看全部评分

 楼主| 发表于 2017-9-26 17:23:00 | 显示全部楼层
回复  cashiba
我用的是这个。。。忘记是什么地方收集来的。。
yamakawa 发表于 2017-9-25 20:05

有了自定义函数就不是问题了,虽然不会用Dllcall,也看不懂......
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-25 08:32 , Processed in 0.094392 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表