通过bufio计算行数

时间:2015-04-10 10:39:58

标签: go

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

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

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

4 个答案:

答案 0 :(得分:4)

你可以这样做:

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

答案 1 :(得分: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)
}

答案 2 :(得分:1)

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

  1. 致电scanner.Buffer()并提供足够的max参数。默认情况下,buffer可能很小,因为Scanner足够聪明,可以分配新的Reader。如果您事先不知道总大小,可能会出现问题,例如使用vanilla Scanner接口,并且您有巨大的行 - 内存消耗将相应增长为{{1记录所有行。
  2. 在外部循环中重新创建scanner,这将确保您进一步前进:
  3. 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++
        }
    }
    

答案 3 :(得分:-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)