特定の場所のフォルダ、ファイル一覧を走査(トラバース)する方法のメモ。
何かしらのファイル加工ツールを作るときに役立つかもしれない。
filepathパッケージのWalkによって指定パスからツリー全体の走査が出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package main import ( "fmt" "os" "path/filepath" ) func traverse(path string, info os.FileInfo, err error) error { if info.IsDir() { fmt.Printf(" dir : %s\n", path) return nil } fmt.Printf("file : %s\n", path) return nil } func main() { if err := filepath.Walk("./", traverse); err != nil { fmt.Println(err) } } |
指定パス(”./
“)以下のフォルダ、ファイルに対してtraverse
が呼ばれます。
この例だとフォルダかファイルかだけ確認して出力します。
応用として特定ディレクトリを除いて指定拡張子のものだけを抜き出してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package main import ( "fmt" "os" "path/filepath" "strings" ) var ignoreFolder = []string{ "tmp", "node_modules", } var suffixes = []string{ ".jpg", ".jpeg", } func sliceContain(ss []string, str string) bool { for _, s := range ss { if s == str { return true } } return false } func traverse(path string, info os.FileInfo, err error) error { if info.IsDir() { if sliceContain(ignoreFolder, info.Name()) { return filepath.SkipDir } return nil } ext := filepath.Ext(info.Name()) if sliceContain(suffixes, strings.ToLower(ext)) { fmt.Printf("%s\n", path) } return nil } func main() { if err := filepath.Walk("./", traverse); err != nil { fmt.Println(err) } } |
L17: sliceContain()
はスライスが特定文字列を持つかどうかの判定用です。
L29: filepath.SkipDir
の中身はエラー(errors.New("skip this directory")
)です。
特定ディレクトリでエラーを返してその中の走査を中止しています。
L33: filepath.Ext()
で拡張子を抜き出して条件に合うものだけ出力します。
この構造での実行結果は期待通り folder1\folder2\img.jpg
のみになりました。