Goで再帰的にディレクトリのファイルを取得する方法
はじめに
ディレクトリにあるファイルの一覧を取得したい機会があると思います。シェルの find
みたいな動作を Go で実現する方法の一つとして ioutil.ReadDir を用いて深さ優先探索をする方法があります。その他には filepath.Walk を用いる方法が考えられます。
ioutil.ReadDir を用いた実装例として以下の記事に記載があります。
しかし、どちらの実装も呼び出したときのエラーハンドリングとして panic
ないしは log.Fatal
のいずれかを用いています。もちろんサンプルのプログラムとして記載しているためにこのような実装になっていると想像しています。しかし Go をはじめたばかりの方だとこのようなエラーハンドリングをしているプログラムをそのまま使ってしまう可能性があるなぁ...と思っています。Go では呼び出し元に error を返却して main.go などのエントリーポイントでエラーを出力するのが正しいエラーハンドリングです。
そこで本記事では ioutil.ReadDir を用いて正しくエラーハンドリングする実装例を紹介します。
実装例
例として以下のように 3 つのファイルがあるディレクトリを走査したいと思います。
mypkg ├── dir_b │ └── file_b ├── dir_c │ └── file_c └── file_a
- dir.go
ポイントはディレクトリの場合は再帰的に Dirwalk を呼び出して、ディレクトリツリーの葉(ファイル)に到達するまで探索することです。そして、葉に到達したパスを順次呼び出し元のパスにマージしていきます。
- dir_test.go
以下のようなテストで想定通りファイルの一覧を取得できていることが確認できます。
$ go test -v === RUN TestDirwalk --- PASS: TestDirwalk (0.01s) PASS ok github.com/d-tsuji/go-sandbox/mypkg 0.016s
おわりに
ディレクトリ配下のすべてのファイルを取得でき、丁寧にエラーハンドリングできる実装例を記載しました。皆さんの参考になれば幸いです。