readdir関数 - ディレクトリの内容を読み込む
ディレクトリの内容を読み込むにはreaddir関数を使用します。
readdir ディレクトリハンドル
ディレクトリハンドルはopendir関数によって取得されたものを指定します。戻り値として、ディレクトリの中にあるファイル名が返されます。繰り返し呼び出すことで、ディレクトリの中のすべてのファイルを読みこむことができます。
opendir関数でディレクトリハンドルを取得して、readdir関数で、すべてのファイルを読み込むサンプルプログラムを書いてみます。while文を使って、ひとつづつファイル名を取得しています。
# ディレクトリ名 my $dir = 'study'; # ディレクトリオープン opendir my $dh, $dir or die "Can't open directory $dir: $!"; # すべてのファイルを読み込む while (my $file = readdir $dh) { print "$file\n"; }
出力結果は以下のようにディレクトリに含まれるファイル名の一覧になります。
. .. a.txt b.txt
カレントディレクトリを表す「.」と一つ上の階層のディレクトリを表す「..」が含まれていることに注意してください。
通常は「.」も「..」も必要ないと思います。ですのでnext文を使って、この二つに該当する場合はスキップしましょう。
# すべてのファイルを読み込む while (my $file = readdir $dh) { next if $file eq '.' || $file eq '..'; print "$file\n"; }
これで望んだ結果が得られます。
出力せずに、ファイル一覧を配列にしたい場合は次のように書くといいです。
my @files; while (my $file = readdir $dh) { next if $file eq '.' || $file eq '..'; push @files, $file; }
サブディレクトリも含めてファイル一覧を取得するには?
サブディレクトリも含めて再帰的にファイルを処理したい場合は、File::Findモジュールを使うのがいいです。
glob関数との使い分けを教えてください
Perlではディレクトリハンドルを使わなくってもglob関数を使えば、ファイル名一覧を取得することができます。
glob関数には次のメリットがあります。
- 「.」「..」は含まれていない
- ループ処理をする必要がない。grep関数と組み合わせると便利。
- ベース名ではなくファイル名を完全なパスで取得できる
- ワイルドカード「*」を使える
率直にいうと、readdir関数の出番はあまりなく、ファイル名一覧の取得には、glob関数を使うのが簡単です。
File::Findの実装のように、きっちりと、ディレクトリ単位でファイル一覧を見たい場合などは、必須だと思います。日常的な用途では、glob関数が便利です。