背景
Goでファイル検索を行うプログラムを作成したので備忘録のためにまとめてみました。
今回使う関数
今回はGo1.16から、実装されたWalkDir関数を使っていきます。
WalkDirは、以下のように動作します。
- 第1引数には検索したいルートパスを指定
- 第2引数には無名関数を設定し、その無名関数が検索中の各ファイルやディレクトリに対して呼び出される
この関数を使用すると、指定したルートパス以下に存在するすべてのディレクトリとファイルを再帰的に探索できます。探索時、無名関数には以下の情報がそれぞれ渡されます
- path: 指定したルートパスからの相対パス
- dirEntry: 取得したファイル名またはディレクトリ名、対象がディレクトリかどうかを示す真偽値、その他の詳細情報
- error: アクセス中に発生したエラー情報
公式ドキュメントは下記になります。
WalkDirのドキュメント
https://pkg.go.dev/path/filepath#WalkDir
実際に動かしてみました。
以下のコードでは取得したファイルやディレクトリ名を表示しています。
ここではWalkDirの第1引数に"."を指定しているため、main.goがある階層とその配下のディレクトリ名及びファイル名を取得して表示しています。
ファイル検索プログラム作成
今回は新しく関数を作成して、指定したルートパス配下で特定のファイルがあるかを判断し、存在する場合は相対パスを表示するプログラムを作成してみます。
コードは下記になります。
func fileFound(root string, fileName string) {
err := filepath.WalkDir(root, func(path string, dirEntry os.DirEntry, err error) error {
if err != nil {
return err
}
if dirEntry.Name() == fileName && !dirEntry.IsDir() {
fmt.Println("Found:", path)
return nil
}
return nil
})
if err != nil {
fmt.Println("Error:", err)
}
}
func main() {
fileFound(".", "file")
}
fileFound関数の第1引数には検索したい場所のルートパス、第2引数には検索したいファイル名を渡します。
dirEntry.Name()
でファイル名またはディレクトリ名を取得しています。またdirEntry.IsDir()
でディレクトリかどうかを判断しています。今回はファイル名を取得したいので、!dirEntry.IsDir()
としてファイルであるときにtrueとなるようにしました。
実行結果は下記になり、対象のファイルがあるときはルートパスからの相対パスが表示されていることがわかります。