Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

こんにちわ

現在、ファイルやディレクトリを簡単に操作できる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コマンド凄すぎない?と思いました。
あと、先人の知恵はすごいので、どんどん使っていきましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした