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

golangのioutilべしべし叩いてみた

More than 3 years have passed since last update.

はじめに

ioutilの公開されてる関数ベシベシ叩いてみた記録。
エラー処理についての記載はノイズになるので、書きませぬ。

TempDir(dir, prefix string) (name string, err error)

第一引数(dir)を指定しないとテンポラリ領域にディレクトリを作成する。
TempDirって書いてあったから、シャットダウンフック的な何かがディレクトリ消すかと思ったけどそんなことなかった。

dir, _ := ioutil.TempDir("", "beroringa")
fmt.Println(dir)
defer os.RemoveAll(dir)
result
/tmp/user/1000/beroringa627495697

面白かったとこ

これ。
r = r*1664525 + 1013904223 // constants from Numerical Recipes
何してんのか良く解んなかったから調べてみたら、擬似乱数生成のプログラムに記載があった。

ioutil/tempfile.go
func nextSuffix() string {
    randmu.Lock()
    r := rand
    if r == 0 {
        r = reseed()
    }
    r = r*1664525 + 1013904223 // constants from Numerical Recipes
    rand = r
    randmu.Unlock()
    return strconv.Itoa(int(1e9 + r%1e9))[1:]
}

TempFile(dir, prefix string) (f *os.File, err error)

ioutil.TempDirと同じで、第一引数(dir)を指定しないとテンポラリ領域にファイルを作成する。
こっちもシャットダウンフック的な何かがファイルを消すことはない。

fp, _ := ioutil.TempFile("", "xxx")
fpath := fp.Name()
fmt.Println(fpath)
defer fp.Close()
result
/tmp/user/1000/xxx422381226

WriteFile(filename string, data []byte, perm os.FileMode) error

ファイル名と権限を指定してファイルに指定データを書き込む。

ioutil.WriteFile(fpath, []byte("write!!\n"), 0644)

ReadAll(r io.Reader) ([]byte, error)

バッファリングしながらデータ終端までデータを読み込む。

contents, _ := ioutil.ReadAll(strings.NewReader("ベンサォン"))
fmt.Printf("%q\n", contents)
result
"ベンサォン"

面白かったとこ

panicの捕まえ方。
panic起きてもdeferは呼ばれるから、deferの中でrecover呼んでエラーハンドリングするみたい。
PanicAndRecoverに色々書いてある。後で読も。

ioutil.go
func readall(r io.reader, capacity int64) (b []byte, err error) {
    buf := bytes.newbuffer(make([]byte, 0, capacity))
    // if the buffer overflows, we will get bytes.errtoolarge.
    // return that as an error. any other panic remains.
    defer func() {
        e := recover()
        if e == nil {
            return
        }
        if panicerr, ok := e.(error); ok && panicerr == bytes.errtoolarge {
            err = panicerr
        } else {
            panic(e)
        }
    }()
    _, err = buf.readfrom(r)
    return buf.bytes(), err
}

ReadFile(filename string) ([]byte, error)

ファイルパスを指定してファイルを読み込む。
内部的にはos.Open呼んでファイルのポインタをioutil.ReadAllの呼び先に渡す感じになってる。

// $ cat /tmp/yakiniku.txt
// $ 焼肉たべたい
contents, _ = ioutil.ReadFile("/tmp/yakiniku.txt")
result
焼肉たべたい

ReadDir(dirname string) ([]os.FileInfo, error)

指定ディレクトリ配下のファイルからソート済みのファイルリストを取得する。

files, _ := ioutil.ReadDir("/tmp")
for _, file := range files {
    fmt.Println(file.Name())
}
result
tmp1
tmp2
...

NopCloser(r io.Reader) io.ReadCloser

なにもしないCloserくっつけてReaderCloser作る。

c := ioutil.NopCloser(string.NewReader("キャベツ太郎"))
fmt.Printf("Close() is %v.\n", c.Close())
result
Close() is <nil>.

ioutil.Discard

書き捨てWriter

n, _ = ioutil.Discard.Write([]byte("gomipoyo"))
fmt.Printf("write size is %v byte.\n", n)
result
write size is 8 byte.

面白かったとこ

blackHoleに飲み込まれる感。

ioutil.go
var blackHolePool = sync.Pool{
    New: func() interface{} {
        b := make([]byte, 8192)
        return &b
    },
}

func (devNull) ReadFrom(r io.Reader) (n int64, err error) {
    bufp := blackHolePool.Get().(*[]byte)
    readSize := 0
    for {
        readSize, err = r.Read(*bufp)
        n += int64(readSize)
        if err != nil {
            blackHolePool.Put(bufp)
            if err == io.EOF {
                return n, nil
            }
            return
        }
    }
}

// Discard is an io.Writer on which all Write calls succeed
// without doing anything.
var Discard io.Writer = devNull(0)
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
ユーザーは見つかりませんでした