重複ファイルの検索

picasaで写真から顔を検出する機能があっておもしろいなあと見ていたら、同じ画像ファイルがやたらとたくさんあるのが気になった。もう最近はハードディスクの空き容量がなくなるということがすっかりなくなったが、やっぱり同じファイルがたくさんあるのは気持ち悪いので、重複する画像ファイルを探してリストアップしようと思った。しばらく前にperlでそれを作ってあったので動かしてみたがなかなか終わらない。おかしいなと調べてみるとある場所をずっと繰り返して検索している。以前はちゃんと動いたはずなのに・・・最近perlは使っていず忘れていたのと、pythonの勉強を兼ねてpythonで作ろうとしてみた。しかし、数時間かけたがうまくいかない。

あきらめて、とりあえず画像ファイルをすべてリストアップしてテキストに書き出し、それをexcelで開いてファイル名で並べ替えて重複をチェックしてみた。しかし、ファイル名だけではちぇっくにならない。「1.jpg」という名前でも全然違うファイルがある。perlで作ったときは、ファイルサイズも調べて、サイズと名前が一致するものを重複候補とした。そこまですれば、後は目視でチェックしてもそれほど手間ではなかった。が、pythonで同じ事をやろうとしたがうまくできなかった。くやしいな・・・・




こんなものを作ってみた。

class MyFile:
def __init__(self,name1,size1,path1):
self.name = name1
self.size = size1
self.path = path1
def getName(self):
return self.name
def getSize(self):
return self.size
def getPath(self):
return self.path
file1 = MyFile("taro",110,"c:\\file\\")
file2 = MyFile("jiro",120,"c:\\file\\")
file3 = MyFile("saburo",130,"c:\\file\\")
print file1.getName()
print file2.getPath()
print file2.getSize()


実行してみた。

C:\>python ob.py
taro
c:\file\
120


"MyFile"というクラスを作ってみた。「クラス」というのは、プロトタイプのようなものだ。「概念」と言えばいいだろうか。クラスそのものは実体ではない。

file1 = MyFile("taro",110,"c:\\file\\")


とやって、初めて file1 という「実体」が存在する。これを「インスタンス」と呼ぶ。このクラスを使って、PCに存在するファイルの名前、サイズ、パスを記録するにはどうすればいいか。このクラスを配列にすることができるか?もしくはインスタンス名を変数にすることができるか?・・・・わからない。

考え方を変える。配列に「ファイルサイズ(スペース)ファイル名」、「パス」という順番に記録していく。そしてその配列を全部読んで、別のリストに「ファイルサイズ(スペース)ファイル名」が存在しなければ記録していく。このときすでに存在していれば、サイズとファイル名が両方同じファイルだということになる。

import os
list1=[]
filelist=[]
duplicate_count =0
file_count=0
rootdir = "/"
for (root, dirs, files) in os.walk(rootdir):
for f in files:
name, ext = os.path.splitext(f)
if ext == (".jpg" or ".png" or ".bmp"):
try:
fsize=os.path.getsize(os.path.join(root, f))
except:
print "some error happened. keep on going anyway..."
str1 = str(fsize) + " " + f
list1.append(str1)
list1.append(os.path.join(root, f))
for i in range(len(list1)):
#    print list1[i]
if ((i % 2) == 0):
file_count += 1
if list1[i] in filelist:
print "already exists:  " + list1[i]
duplicate_count += 1
else:
filelist.append(list1[i])