「大切なデータを失ってしまった…」 そんな経験はありませんか? バックアップは重要だと分かっていても、既存のツールは帯に短し襷に長し…。
「なら、自分で作ってしまえばいいじゃない!」
今日から始まる新シリーズ「Perlで作るファイルバックアップツール」では、実用的なツールをゼロから作り上げます。単なるコピープログラムではありません。Template Method や Strategy といったデザインパターンを駆使し、プロの現場でも通用する「変更に強い」アーキテクチャを学びます。
初回の今日は、まずは「動くもの」を作るところからスタートです。
今回の目標
- 指定したディレクトリを別の場所に再帰的にコピーするツールを作る
- ファイル操作の基本(
File::Copy,File::Findなど)を確認する - ベンチマークを取り、現状の課題を洗い出す
単純なコピーの実装
まずは、CPANモジュールを使わずに、標準モジュールだけで実装してみましょう。Perlには File::Copy や File::Path などの便利なコアモジュールがあります。
再帰的コピーのロジック
ディレクトリを丸ごとコピーするには、ディレクトリツリーを再帰的に辿る必要があります。ここでは File::Find を使っても良いですが、よりモダンで扱いやすい Path::Tiny を使った実装を紹介したいところですが…今回は「基本を知る」ために、あえて標準的な手法と少しの現代的な書き方(Moo はまだ使いません)で書いてみます。
といっても、車輪の再発明は避けたいので、File::Copy::Recursive のような挙動を自前で書くイメージを持ちつつ、今回はシンプルに Path::Tiny を使ってサクッと実装してしまいましょう。おっと、標準モジュールと言いましたが、Path::Tiny は現代のPerl開発ではほぼ標準と言っても過言ではないので、これを使います。ない場合は cpanm Path::Tiny でインストールしてください。
| |
とてもシンプルですね。Path::Tiny のおかげで、イテレータを使った再帰処理も直感的に書けます。
ベンチマーク:単純コピーの弱点
さて、このツールは「動きます」。しかし、バックアップツールとして常用するには大きな問題があります。それは 「毎回すべてのファイルをコピーしている」 という点です。
実際に試してみましょう。適当なディレクトリ(例えば写真フォルダやプロジェクトフォルダなど、数千ファイルあるもの)を用意して、2回連続で実行してみます。
| |
2回目もほぼ同じ時間がかかっていますね。ファイルに変更がなくても、すべて上書きコピーしているからです。これでは、ファイル数が増えれば増えるほど時間がかかり、ディスクI/Oも無駄に消費してしまいます。
欠点の整理
- 遅い: 変更されていないファイルまでコピーしている
- 無駄: ディスクへの書き込み負荷が高い
- 拡張性がない: 「圧縮したい」「特定のファイルを除外したい」といった要望が出たとき、この
whileループの中にif文を継ぎ足していくことになり、コードがスパゲッティ化しやすい
次回予告
「動くけれど、実用的ではない」状態からスタートしました。次回は、バックアップの基本中の基本である 「差分バックアップ」 を実装することで、見違えるほど高速化させてみます。
そこで登場するのが、ファイルのメタデータ(タイムスタンプ)の活用です。
お楽しみに!
