Golangで、ファイル一覧取得(最新順出力)

  • 21
    Like
  • 2
    Comment
More than 1 year has passed since last update.
package main

import (
        "flag"
        "fmt"
        "io/ioutil"
        "os"
        "path"
        "sort"
)

type FileInfos []os.FileInfo
type ByName struct{ FileInfos }

func (fi ByName) Len() int {
        return len(fi.FileInfos)
}
func (fi ByName) Swap(i, j int) {
        fi.FileInfos[i], fi.FileInfos[j] = fi.FileInfos[j], fi.FileInfos[i]
}
func (fi ByName) Less(i, j int) bool {
        return fi.FileInfos[j].ModTime().Unix() < fi.FileInfos[i].ModTime().Unix()
}

// 指定されたファイル名がディレクトリかどうか調べる
func IsDirectory(name string) (isDir bool, err error) {
        fInfo, err := os.Stat(name) // FileInfo型が返る。
        if err != nil {
                return false, err // もしエラーならエラー情報を返す
        }
        // ディレクトリかどうかチェック
        return fInfo.IsDir(), nil
}

func main() {
        var arg string

        // -fオプション flag.Arg(0)だとファイル名が展開されてしまうようなので
        flag.StringVar(&arg, "f", "", "SearchPattern")
        // コマンドライン引数を解析
        flag.Parse()

        // カレントディレクトリの取得
        var curDir, _ = os.Getwd()
        curDir += "/"

        // 引数が取得できなければ、カレントディレクトリを使用
        if arg == "" {
                arg = curDir
        }

        // ディレクトリとファイル名に分割して格納
        var dirName, filePattern = path.Split(arg)

        // ディレクトリが無いならばカレントディレクトリを使用
        if dirName == "" {
                dirName = curDir
        }

        // 取得しようとしているパスがディレクトリかチェック
        var isDir, _ = IsDirectory(dirName + filePattern)

        // ディレクトリならば、そのディレクトリ配下のファイルを調べる。
        if isDir == true {
                dirName = dirName + filePattern
                filePattern = ""
        }

        // ディレクトリ内のファイル情報の読み込み[] *os.FileInfoが返る。
        fileInfos, err := ioutil.ReadDir(dirName)

        // ディレクトリの読み込みに失敗したらエラーで終了
        if err != nil {
                fmt.Errorf("Directory cannot read %s\n", err)
                os.Exit(1)
        }

        // ファイル情報を一つずつ表示する
        sort.Sort(ByName{fileInfos})
        for _, fileInfo := range fileInfos {
                // *FileInfo型
                var findName = (fileInfo).Name()
                var matched = true
                // lsのようなワイルドカード検索を行うため、path.Matchを呼び出す
                if filePattern != "" {
                        matched, _ = path.Match(filePattern, findName)
                }
                // path.Matchでマッチした場合、ファイル名を表示
                if matched == true {
                        fmt.Printf("%s\n", findName)
                }
        }
}

次回は説明を交えて、綺麗に分割していきます。