LoginSignup
6
2

More than 5 years have passed since last update.

Goでファイルとディレクトリのパーミッション、日時などを取得する

Posted at

こんにちわ

現在、ファイルやディレクトリを簡単に操作できるTUIを作っていて、
ファイルやディレクトリの情報を取得して表示する必要があり、調べたら意外と面倒だったので、
忘れないうちに備忘録として残ります。

とりあえず今、画面はこんな感じです。
image.png

ディレクトリ内のファイル・ディレクトリを取得

Goではfilepath.WalkFuncでディレクトリ内のファイル・ディレクトリを再帰的に取得してくれますが、
今回はカレントディレクトリの情報を取得できればいいので、ioutil.ReadDirを使用します。

ReadDirを使用すると、[]os.FileInfo構造体を取得できます。

type FileInfo interface {
        Name() string       // ファイル名
        Size() int64        // ファイルサイズ
        Mode() FileMode     // パーミッション
        ModTime() time.Time // 更新日
        IsDir() bool        // ディレクトリの場合はtrue
        Sys() interface{}   // syscall.Stat_tに型アサーションすると更に詳細情報を取得可能
}

とこんな感じでデータを取得できます。

パーミッション

FileInfo.Mode().String()でおなじみのフォーマットに変換してくれます。

OwnerとGroup

ファイルの所有者と所有者が所属しているグループを取得したい場合は、
FilInfo.Sys()sysacll.Stat_tに型アサーションする必要があります。

if stat, ok := file.Sys().(*syscall.Stat_t); ok {
    // syscall.Stat_t.UidがユーザIDになります
    uid := strconv.Itoa(int(stat.Uid))
    // os/userパッケージのLookupIdにUidを渡すとユーザ名を取得できます
    u, err := user.LookupId(uid)
    if err != nil {
        owner = uid
    } else {
        owner = u.Username
    }

    // syscall.Stat_t.GidがグループIDになります
    gid := strconv.Itoa(int(stat.Gid))
    // os/userパッケージのLookupGroupIdにGidを渡すとグループ名を取得できます
    g, err := user.LookupGroupId(gid)
    if err != nil {
        group = gid
    } else {
        group = g.Name
    }
}

日時

作成日や更新日などを取得したい場合、OSごとに取得方法が異なります。
syscall.Stat_tに更新日などのフィールドがありますが、OSごとにフィールドが異なります。
Macの場合はこうなっています。
Linuxの場合、Birthtimespecに相当するフィールドはない様です。

type Stat_t struct {
    // 日時の部分だけ抽出
    Atimespec     Timespec
    Mtimespec     Timespec
    Ctimespec     Timespec
    Birthtimespec Timespec
}

自前で実装は結構大変なので、ここは先人の知恵を借ります。
こちらのライブラリを使用すると、差分吸収してくれます。
OSによっては取得できないデータもあるのでご注意を。

まとめ

ファイル情報を取得するだけなのに何かと面倒ですね。
lsコマンド凄すぎない?と思いました。
あと、先人の知恵はすごいので、どんどん使っていきましょう。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2