2つのファイルやフォルダーを比較して相違点をみつけるファイルコンペアツールを作成します。これもフリーで使えるものがたくさんありますが、勉強用で作ってみました。

外観はこんな感じです。

ファイルサイズが大きい場合、時間がかかるので進行状態がわかるようにプログレスバーをつけました。上がファイルの個数、下がひとつのファイルのコンペアの進行状況を知るためのものです。

最初に比較元と比較先のパスを入力する必要がありますが、ドラッグ&ドロップでできるようにしました。

なにかがドラッグオーバーされたらファイルがどうか調べます。

そしてドロップされたらファイルパスを取得してテキストボックスに表示させます。

[比較]ボタンがクリックされたらコンペアを開始します。

テキストボックスに入力されている文字列は適切な内容でしょうか? ファイル名かフォルダ名か調べます。また入力内容が同じ場合はエラーを返します。

両方ともファイル、または両方ともフォルダの場合はコンペアを実行します。一方がフォルダでもう片方がファイルの場合は当然「両者の内容は異なる」という結果になります。

ファイル同士の比較が簡単なので先にやってしまいましょう。

このメソッドが呼ばれるときは引数がファイルかフォルダのパスであることははっきりしています。ただファイルなのかフォルダなのかはわかりません。両方とも同じ名前のフォルダである場合は「同じ」と判断しています。

ファイルの場合はまずサイズを調べます。同じでないならふたつのファイルの内容は異なることがわかります。同じ場合は FileStream.ReadByte()で1バイトずつ読み取って同じ値かどうか調べています。いつまで繰り返すのかというと違いが見つかるか、ファイルの終端にたどり着くまでです。最後に取得された値を比較することでファイルの内容が同じかどうかがわかります。

ファイルサイズが大きい場合、時間がかかります。ユーザーとしてはどれくらい待てばいいかわかるようにプログレスバーと文字情報で進行状態を示します。ただ頻繁にこれを繰り返すと処理が遅くなるだけなので、

ファイルサイズが20MBより大きい場合で、1MBぶんの処理が終わったときだけ表示を変更させています。

違いがみつかったらどこが違うのかわかるようにしています。

フォルダ同士の比較はどうすればいいでしょうか?

まずフォルダ内のフォルダとファイルのパスを調べます。そしてそれぞれの結果からフォルダのパスを取り除きます。

フォルダ C:\aaaを調べたら C:\aaa\xxx\abc.txtがみつかり、D:\bbbを調べたら D:\bbb\xxx\abc.txtが見つかったときは、C:\aaaとD:\bbbを取り除くと\xxx\abc.txtが残ります。この場合、調査対象のフォルダ内には同じ名前のフォルダとファイルが存在することがわかります。

比較元のフォルダには存在するけれども比較先のフォルダに存在しない場合、これらを表示させます。

両方に存在するファイルがわかったら本当に内容が同じなのか比較します。

比較が終わったらリスト内に結果を格納して、処理が終わったら結果を表示させます。

実際にこれまでに作成したコードとバックアップしているものを比較してみました。

最後にちょっとだけ自慢。

こいつと勝負したら勝った♪

高速ファイル比較ツール
決定版! 高速に2つのファイル(フォルダ,ドライブ単位も)のコンペア(比較),軽い使い勝手良い,PC1台に1つ便利

赤枠部分の表示で時間がかかっているものと思われます。