以下の内容はhttps://devlights.hatenablog.com/entry/2025/09/10/073000より取得しました。


Goメモ-614 (bufio.ScannerにBufferメソッドでバッファサイズを設定)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

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

bufio.Scannerは、皆さんよく利用されていると思います。便利ですね。

で、このscannerさんの典型的なパターンは以下のようになります。

s := bufio.NewScanner(r)
for s.Scan() {
    txt := s.Text()
}

if err := s.Err(); err != nil {
}

と、最後にエラーがあるかどうかを取得するコードがありますが、普通に使っている限りほぼエラーなんて見ないはずです。

で、どのような場合にエラーが出るかというと、「読み取る対象の行データが超長い場合」などがあります。

bufio.Scannerが内部で持っているバッファのサイズはデフォルトで64KBです。なので、これを超える場合エラーになります。

そのようなデータに対して、読み取りを行いたい場合は自前でバッファを確保しておいて、それを bufio.Scanner.Buffer に渡してあげます。

以下に自分のメモ代わりに挙動の違いをメモメモ。。。

サンプル

buffersize.go

package scannerop

import (
    "bufio"
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "strings"
)

// BufferSize は、bufio.Scanner.Buffer()にてバッファサイズを設定することによる挙動の違いについてのサンプルです.
//
// # REFERENCES
//   - https://pkg.go.dev/bufio@go1.25.0#Scanner.Buffer
func BufferSize() error {

    // Scannerのデフォルトバッファサイズ (64KB) を超える文字列を生成
    var (
        s   = strings.Repeat("a", 65536)
        m   = map[string]string{"field": s}
        buf = bytes.NewBuffer(nil)
        enc = json.NewEncoder(buf)
        err error
    )
    enc.SetEscapeHTML(false)
    enc.SetIndent("", "")
    if err = enc.Encode(m); err != nil {
        return err
    }

    fmt.Printf("一行のバイトサイズ: %dbytes\n\n", buf.Len())

    // デフォルトバッファ(64KB)で読み込み
    fmt.Println("[デフォルトバッファサイズで読み込み]")
    {
        var (
            scanner = bufio.NewScanner(buf)
        )
        for scanner.Scan() {
            fmt.Fprintln(io.Discard, scanner.Text())
        }

        fmt.Printf("\t結果: %v\n", scanner.Err())
    }

    // バッファを拡張(1MB)して読み込み
    fmt.Println("[拡張バッファサイズで読み込み]")
    {
        var (
            scannerBuf = make([]byte, 1024*1024)
            scanner    = bufio.NewScanner(buf)
        )
        scanner.Buffer(scannerBuf, cap(scannerBuf))
        for scanner.Scan() {
            fmt.Fprintln(io.Discard, scanner.Text())
        }

        fmt.Printf("\t結果: %v\n", scanner.Err())
    }

    return nil
}

実行結果

       $ task
        task: [build] go build -o "/workspace/try-golang/try-golang" .
        task: [run] ./try-golang -onetime

        ENTER EXAMPLE NAME: scannerop_buffer

        [Name] "scannerop_buffer"
        一行のバイトサイズ: 65549bytes

        [デフォルトバッファサイズで読み込み]
                結果: bufio.Scanner: token too long
        [拡張バッファサイズで読み込み]
                結果: <nil>


        [Elapsed] 587.68µs

参考情報

Goのおすすめ書籍


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

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




以上の内容はhttps://devlights.hatenablog.com/entry/2025/09/10/073000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14