いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-275 (ファイルが読み込み・書き込み・実行可能かどうかを判定(2))

概要

以下、自分用のメモです。

たまに使いたいときによく忘れているので、ここにメモメモ。。。

前回、ファイルの読み込み・書き込み・実行可能かどうかを判定するサンプルを書いてましたが

devlights.hatenablog.com

ついでなので、もう少しライブラリっぽくしたものを作りました。

以下にアップしていますので、よかったらご参考まで。

github.com

サンプル

stat.go

package stat

// Stat は、ファイルの読み取り・書き込み・実行の権限状態を判定するためのインターフェースを持ちます。
type Stat interface {
    // 読み込み可能かどうか
    CanRead() bool
    // 書き込み可能かどうか
    CanWrite() bool
    // 実行可能かどうか
    CanExecute() bool
}

user.go

package stat

import "io/fs"

type userStat struct {
    fi fs.FileInfo
}

// User は、指定された fs.FileInfo からユーザの 読み取り・書き込み・実行の権限状態を判定します。
func User(fi fs.FileInfo) Stat {
    return userStat{fi}
}

func (me userStat) CanRead() bool {
    return me.fi.Mode().Perm()&0400 == 0400
}

func (me userStat) CanWrite() bool {
    return me.fi.Mode().Perm()&0200 == 0200
}

func (me userStat) CanExecute() bool {
    return me.fi.Mode().Perm()&0100 == 0100
}

group.go

package stat

import "io/fs"

type groupStat struct {
    fi fs.FileInfo
}

// Group は、指定された fs.FileInfo からグループの 読み取り・書き込み・実行の権限状態を判定します。
func Group(fi fs.FileInfo) Stat {
    return groupStat{fi}
}

func (me groupStat) CanRead() bool {
    return me.fi.Mode().Perm()&0040 == 0040
}

func (me groupStat) CanWrite() bool {
    return me.fi.Mode().Perm()&0020 == 0020
}

func (me groupStat) CanExecute() bool {
    return me.fi.Mode().Perm()&0010 == 0010
}

other.go

package stat

import "io/fs"

type otherStat struct {
    fi fs.FileInfo
}

// Other は、指定された fs.FileInfo から他者の 読み取り・書き込み・実行の権限状態を判定します。
func Other(fi fs.FileInfo) Stat {
    return otherStat{fi}
}

func (me otherStat) CanRead() bool {
    return me.fi.Mode().Perm()&0004 == 0004
}

func (me otherStat) CanWrite() bool {
    return me.fi.Mode().Perm()&0002 == 0002
}

func (me otherStat) CanExecute() bool {
    return me.fi.Mode().Perm()&0001 == 0001
}

テスト

package stat_test

import (
    "testing"

    "github.com/devlights/gomy/fileio/stat"
)

func TestUserStat(t *testing.T) {
    // r--
    {
        f, fi, err := tmpAndChmodAndStat(0400)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.User(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(r && !w && !x) {
            t.Errorf("[want] true, false, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }
    // -w-
    {
        f, fi, err := tmpAndChmodAndStat(0200)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.User(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && w && !x) {
            t.Errorf("[want] false, true, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }

    // --x
    {
        f, fi, err := tmpAndChmodAndStat(0100)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.User(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && !w && x) {
            t.Errorf("[want] false, false, true\t[got] %v, %v, %v\n", r, w, x)
        }
    }
}

func TestGroupStat(t *testing.T) {
    // r--
    {
        f, fi, err := tmpAndChmodAndStat(0040)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Group(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(r && !w && !x) {
            t.Errorf("[want] true, false, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }
    // -w-
    {
        f, fi, err := tmpAndChmodAndStat(0020)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Group(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && w && !x) {
            t.Errorf("[want] false, true, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }

    // --x
    {
        f, fi, err := tmpAndChmodAndStat(0010)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Group(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && !w && x) {
            t.Errorf("[want] false, false, true\t[got] %v, %v, %v\n", r, w, x)
        }
    }
}

func TestOtherStat(t *testing.T) {
    // r--
    {
        f, fi, err := tmpAndChmodAndStat(0004)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Other(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(r && !w && !x) {
            t.Errorf("[want] true, false, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }
    // -w-
    {
        f, fi, err := tmpAndChmodAndStat(0002)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Other(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && w && !x) {
            t.Errorf("[want] false, true, false\t[got] %v, %v, %v\n", r, w, x)
        }
    }

    // --x
    {
        f, fi, err := tmpAndChmodAndStat(0001)
        if err != nil {
            t.Error(err)
        }
        defer f.Close()

        var (
            s = stat.Other(fi)
            r = s.CanRead()
            w = s.CanWrite()
            x = s.CanExecute()
        )

        if !(!r && !w && x) {
            t.Errorf("[want] false, false, true\t[got] %v, %v, %v\n", r, w, x)
        }
    }
}

参考情報

https://pkg.go.dev/io/fs@go1.19.3#FileMode.Perm

https://pkg.go.dev/io/fs@go1.19.3#FileMode

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。