通过bufio计算行数

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

我正在利用bufio为文本文件中的每一行执行for循环。我不知道如何计算行数。

scanner := bufio.NewScanner(bufio.NewReader(file))

以上就是我用来扫描文件的内容。

go
4个回答
4
投票

你可以这样做:

counter := 0
for scanner.Scan() {
    line := scanner.Text()
    counter++
    // do something with your line
}
fmt.Printf("Lines read: %d", counter)

1
投票

保持简单快速。不需要缓冲,scanner已经这样做了。不要做不必要的string转换。例如,

package main

import (
    "bufio"
    "fmt"
    "os"
)

func lineCount(filename string) (int64, error) {
    lc := int64(0)
    f, err := os.Open(filename)
    if err != nil {
        return 0, err
    }
    defer f.Close()
    s := bufio.NewScanner(f)
    for s.Scan() {
        lc++
    }
    return lc, s.Err()
}

func main() {
    filename := `testfile`
    lc, err := lineCount(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(filename+" line count:", lc)
}

1
投票

正如我评论的那样,接受的答案在很长时间内都失败了。默认限制是bufio.MaxScanTokenSize,即64KiB。因此,如果您的行超过65536个字符,它将无声地失败。你有两个选择。

  1. 调用scanner.Buffer()并提供足够的max参数。 buffer默认可能很小,因为Scanner足够聪明,可以分配新的。如果您事先不知道总大小,可能会出现问题,例如vanilla Reader界面,并且您有大线 - 内存消耗将相应增长,因为Scanner记录了所有行。
  2. 在外循环中重新创建scanner,这将确保您进一步前进:
var scanner *bufio.Scanner
counter := 0
for scanner == nil || scanner.Err() == bufio.ErrTooLong {
    scanner = bufio.NewScanner(reader)
    for scanner.Scan() {
        counter++
    }
}

(2)的问题是你继续分配和释放缓冲区而不是重用它们。所以让我们融合(1)和(2):

var scanner *bufio.Scanner
buffer := make([]byte, bufio.MaxScanTokenSize)
counter := 0
for scanner == nil || scanner.Err() == bufio.ErrTooLong {
    scanner = bufio.NewScanner(reader)
    scanner.Buffer(buffer, 0)
    for scanner.Scan() {
        counter++
    }
}

-1
投票

这是我完成任务的方法:

inputFile, err := os.Open("input.txt")

if err != nil {
    panic("Error happend during opening the file. Please check if file exists!")
    os.Exit(1)
}

defer inputFile.Close()

inputReader := bufio.NewReader(inputFile)

scanner := bufio.NewScanner(inputReader)
// Count the words.
count := 0
for scanner.Scan() {
    line := scanner.Text()
    fmt.Printf("%v\n", line)
    count++
}
if err := scanner.Err(); err != nil {
    fmt.Fprintln(os.Stderr, "reading input:", err)
}
fmt.Printf("%d\n", count)
© www.soinside.com 2019 - 2024. All rights reserved.