使用Coldfusion搜索文件夹(递归)以查找重复的照片?

时间:2011-06-19 01:41:26

标签: coldfusion duplicates

移动和备份我的照片集几次后,我有几张重复的照片,各种文件夹中的不同文件名分散在我的电脑上。所以我想我会写一个快速的CF(9)页面来找到重复项(然后可以稍后添加代码以允许我删除它们)。

我有几个问题: -

  1. 目前我只是使用文件大小来匹配图像文件,但我认为匹配的EXIF数据或图像文件二进制的匹配哈希会更可靠吗?

  2. 我把这些代码捆绑在一起,但是如何才能在网络外部搜索?

  3. 有更好的方法吗?

  4. P

    <cfdirectory 
    name="myfiles" 
    directory="C:\ColdFusion9\wwwroot\images\photos" 
    filter="*.jpg"
    recurse="true"
    sort="size DESC"
    type="file" >
    
    
    <cfset matchingCount=0>
    <cfset duplicatesFound=0>
    <table border=1>
    <cfloop query="myFiles" endrow="#myfiles.recordcount#-1">
    
        <cfif myfiles.size is myfiles.size[currentrow + 1]>
            <!---this file is the same size as the next row--->
            <cfset matchingCount = matchingCount + 1>
            <cfset duplicatesFound=1>
        <cfelse>
            <!--- the next file is a different size --->
    
            <!--- if there have been matches, display them now ---> 
            <cfif matchingCount gt 0>   
    
                <cfset sRow=#currentrow#-#matchingCount#>
                <cfoutput><tr>
                <cfloop index="i" from="#sRow#" to="#currentrow#"> 
                        <cfset imgURL=#replace(directory[i], "C:\ColdFusion9\wwwroot\", "http://localhost:8500/")#>
                        <td><a href="#imgURL#\#name[i]#"><img height=200 width=200 src="#imgURL#\#name[i]#"></a></td>
                </cfloop></tr><tr>
                <cfloop index="i" from="#sRow#" to="#currentrow#"> 
                    <td width=200>#name[i]#<br>#directory[i]#</td>
                </cfloop>
                </tr>
                </cfoutput>
    
                <cfset matchingCount = 0>
    
            </cfif> 
        </cfif>
    </cfloop>
    </table>
    <cfif duplicatesFound is 0><cfoutput>No duplicate jpgs found</cfoutput></cfif>
    

2 个答案:

答案 0 :(得分:3)

这是非常有趣的任务,所以我决定尝试一下。

首先,我的笔记本电脑上有4GB内存,2x2.26Ghz CPU和SSD的一些测试结果:1,143张图像,总计263.8MB。

ACF9:重复8次,耗时~2.3秒

Railo 3.3:8重复,花了~2.0秒(耶!)

我使用了来自this SO answer的精彩提示来选择最佳的哈希选项。

所以,这就是我所做的:

<cfsetting enablecfoutputonly="true" />

<cfset ticks = getTickCount() />

<!--- this is great set of utils from Apache --->
<cfset digestUtils = CreateObject("java","org.apache.commons.codec.digest.DigestUtils") />

<!--- cache containers --->
<cfset checksums = {} />
<cfset duplicates = {} />

<cfdirectory
    action="list"
    name="images"
    directory="/home/trovich/images/"
    filter="*.png|*.jpg|*.jpeg|*.gif"
    recurse="true" />

<cfloop query="images">

    <!--- change delimiter to \ if you're on windoze --->
    <cfset ipath = images.directory & "/" & images.name />

    <cffile action="readbinary" file="#ipath#" variable="binimage" />

    <!---
        This is slow as hell with any encoding!
        <cfset checksum = BinaryEncode(binimage, "Base64") />
     --->

    <cfset checksum = digestUtils.md5hex(binimage) />

    <cfif StructKeyExists(checksums, checksum)>

        <!--- init cache using original on 1st position when duplicate found --->
        <cfif NOT StructKeyExists(duplicates, checksum)>
            <cfset duplicates[checksum] = [] />
            <cfset ArrayAppend(duplicates[checksum], checksums[checksum]) />
        </cfif>

        <!--- append current duplicate --->
        <cfset ArrayAppend(duplicates[checksum], ipath) />

    <cfelse>

        <!--- save originals only into the cache --->
        <cfset checksums[checksum] = ipath />

    </cfif>

</cfloop>

<cfset time = NumberFormat((getTickcount()-ticks)/1000, "._") />


<!--- render duplicates without resizing (see options of cfimage for this) --->

<cfoutput>

<h1>Found #StructCount(duplicates)# duplicates, took ~#time# s</h1>

<cfloop collection="#duplicates#" item="checksum">
<p>
    <!--- display all found paths of duplicate --->
    <cfloop array="#duplicates[checksum]#" index="path">
        #HTMLEditFormat(path)#<br/>
    </cfloop>
    <!--- render only last duplicate, they are the same image any way --->
    <cfimage action="writeToBrowser" source="#path#" />
</p>
</cfloop>

</cfoutput>

显然,您可以轻松使用duplicates数组来查看结果和/或运行一些清理工作。

玩得开心!

答案 1 :(得分:0)

我建议将检查代码拆分为只接受文件名的函数。

然后使用全局结构来检查重复项,键是“size”或“size_hash”,值可以是一个包含与该键匹配的所有文件名的数组。

在所有不同目录中的所有jpeg文件上运行该函数,然后扫描结构并报告其数组中包含多个文件的所有条目。

如果您想在webroot外部显示图片,可以通过&lt; cfcontent file =“#filename#”type =“image / jpeg”&gt;