Home About
Golang

Golang, listFiles 指定のディレクトリ内のファイルまたはディレクトリを列挙する

Golang でそれをする方法の備忘録。

改良版をこちらに書いた。

package main

import (
    "fmt"
    "os"
)

func main() {
    postsPath := "posts"
    f, err := os.Open(postsPath)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    callbackDirName := func(dirName string) {
        fmt.Println( fmt.Sprintf("dir: %s", dirName))
    }
    callbackFileName := func(fileName string) {
        fmt.Println( fmt.Sprintf("file: %s", fileName))
    }

    fileInfos, err := f.Readdir(0)
    for _, fileInfo := range fileInfos {
        if fileInfo.IsDir() {
            callbackDirName(fileInfo.Name())
        } else {
            callbackFileName(fileInfo.Name())
        }
    }
}

これを改良しよう。
main 関数では、指定のディレクトリ内にあるファイルとディレクトリを知りたいだけなので、それだけのコードにしたい。 つまり、listFiles という関数をつくり、実際の処理コードはそちらに移し、main 関数では結果だけを受け取ることができるように改良。

package main

import (
	"fmt"
	"os"
)

type CallbackName func(string)

func listFiles(pathName string, callbackDirName CallbackName, callbackFileName CallbackName) error {
	f, err := os.Open(pathName)
	if err != nil {
		return err
	}
	defer f.Close()

	fileInfos, err := f.Readdir(0)
	for _, fileInfo := range fileInfos {
		if fileInfo.IsDir() {
			callbackDirName(fileInfo.Name())
		} else {
			callbackFileName(fileInfo.Name())
		}
	}

	return nil
}

func main() {
	postsPath := "posts"

	callbackDirName := func(dirName string) {
		fmt.Println(fmt.Sprintf("dir: %s", dirName))
	}

	callbackFileName := func(fileName string) {
		fmt.Println(fmt.Sprintf("file: %s", fileName))
	}

	listFiles(postsPath, callbackDirName, callbackFileName)
}

listFiles 関数の引数に関数(CallbackName) を渡せるのは便利ですね。