Golang bufio.Scanner:令牌太长

问题描述 投票:0回答:1

我有一个大文件(内存太大),我需要用分隔符“|”解析每个记录。问题是,每个记录都有不同的大小,这就是为什么我总是收到错误“bufio.Scanner:令牌太长”。

如果我遇到 bufio.Scanner: token too long 错误,有什么办法可以用更大的缓冲区重试扫描吗?或者 bufio.Scanner 在我的情况下不是正确的选择,因为我不知道每条记录的确切大小?

谢谢你

https://go.dev/play/p/Erx15nXXCGk

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "strings"
)

func main() {
    // Example byte array
    byteArray := []byte("data1|data2|data3|data4|data5|data6|data7|data8|data9|data10")

    // Buffer size for reading chunks
    bufferSize := 6
    buf := make([]byte, bufferSize)

    // Create a bufio.Scanner with a custom split function
    scanner := bufio.NewScanner(bytes.NewReader(byteArray))
    scanner.Buffer(buf, bufferSize)
    scanner.Split(splitFunc)

    // Read the byte array in chunks
    for scanner.Scan() {
        // Process each token (chunk)
        chunk := scanner.Text()
        fmt.Println("Chunk:", chunk, "Chunk Length:", len(chunk))
    }
    if err := scanner.Err(); err != nil {
        if err == bufio.ErrTooLong {
            fmt.Println("Error:", err)
            fmt.Printf("Buffer size %d is too small...\n", bufferSize)
        } else {
            fmt.Println("Error:", err)
        }
    }
}

func splitFunc(data []byte, atEOF bool) (advance int, token []byte, err error) {

    // Return nothing if at end of file and no data passed
    if atEOF && len(data) == 0 {
        return 0, nil, nil
    }

    if i := strings.Index(string(data), "|"); i >= 0 {
        return i + 1, data[0:i], nil
    }

    // If at end of file with data return the data
    if atEOF {
        return len(data), data, nil
    }

    return
}
file go memory error-handling split
1个回答
0
投票
scanner.Buffer(buf, bufferSize)

您不需要提供任何缓冲区

默认情况下,Scanner.Scan 使用内部缓冲区并将最大令牌大小设置为 MaxScanTokenSize。

如果您只是将其删除,程序就可以正常工作。您将受到 MaxScanTokenSize 的限制,它似乎是 64k。

© www.soinside.com 2019 - 2024. All rights reserved.