Go by Example: ファイルの読み取り

ファイルの読み取りと書き込みは、多くの Go プログラムに必要な基本的なタスクです。まず、ファイルの読み取りの例をいくつか紹介します。

package main
import (
    "bufio"
    "fmt"
    "io"
    "os"
)

ファイルを読み取るには、ほとんどの呼び出しでエラーをチェックする必要があります。このヘルパーは、以下のエラーチェックを簡略化します。

func check(e error) {
    if e != nil {
        panic(e)
    }
}
func main() {

おそらく最も基本的なファイル読み取りタスクは、ファイルのコンテンツ全体をメモリに取り込むことです。

    dat, err := os.ReadFile("/tmp/dat")
    check(err)
    fmt.Print(string(dat))

ファイルのどの部分を読み取るのか、またどのように読み取るのかをより詳細に制御したい場合もあります。このようなタスクでは、最初に Open を使用してファイルを os.File 値として取得します。

    f, err := os.Open("/tmp/dat")
    check(err)

ファイルの先頭からいくつかのバイトを読み取ります。最大 5 バイトを読み取ることもできますが、実際に読み込まれたバイト数も確認します。

    b1 := make([]byte, 5)
    n1, err := f.Read(b1)
    check(err)
    fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))

また、ファイル内の既知の場所に Seek し、そこから Read することもできます。

    o2, err := f.Seek(6, io.SeekStart)
    check(err)
    b2 := make([]byte, 2)
    n2, err := f.Read(b2)
    check(err)
    fmt.Printf("%d bytes @ %d: ", n2, o2)
    fmt.Printf("%v\n", string(b2[:n2]))

他のシーク方法は、現在のカーソルの位置を基準としており、

    _, err = f.Seek(4, io.SeekCurrent)
    check(err)

ファイルの末尾を基準としています。

    _, err = f.Seek(-10, io.SeekEnd)
    check(err)

io パッケージでは、ファイルの読み取りに役立つ可能性のある関数がいくつか用意されています。たとえば、上記のような読み取りは ReadAtLeast を使用してより堅牢に実装できます。

    o3, err := f.Seek(6, io.SeekStart)
    check(err)
    b3 := make([]byte, 2)
    n3, err := io.ReadAtLeast(f, b3, 2)
    check(err)
    fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))

組み込みのリワインド機能はありませんが、Seek(0, io.SeekStart) で実現できます。

    _, err = f.Seek(0, io.SeekStart)
    check(err)

bufio パッケージは、多数の小規模な読み取りで効率的であることと、追加の読み取り方法が提供されるという両方の理由から、有用な可能性があります。

    r4 := bufio.NewReader(f)
    b4, err := r4.Peek(5)
    check(err)
    fmt.Printf("5 bytes: %s\n", string(b4))

完了したら、ファイルは閉じます(通常は Open の直後に defer を使用してスケジュールされる必要があります)。

    f.Close()
}
$ echo "hello" > /tmp/dat
$ echo "go" >>   /tmp/dat
$ go run reading-files.go
hello
go
5 bytes: hello
2 bytes @ 6: go
2 bytes @ 6: go
5 bytes: hello

次に、ファイルの書き込みについて説明します。

次の例:ファイルの書き込み