首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Go中逐行读取文件

在Go中逐行读取文件
EN

Stack Overflow用户
提问于 2012-01-06 19:50:25
回答 10查看 412.5K关注 0票数 433

我在Go中找不到file.ReadLine函数。我可以想出如何快速编写一个,但我只是想知道我是不是忽略了这里的一些东西。如何逐行阅读文件?

EN

回答 10

Stack Overflow用户

发布于 2013-05-18 02:21:54

在Go 1.1和更新版本中,最简单的方法是使用bufio.Scanner。下面是一个从文件中读取行的简单示例:

代码语言:javascript
复制
package main

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

func main() {
    file, err := os.Open("/path/to/file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    // optionally, resize scanner's capacity for lines over 64K, see next example
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
}

这是从Reader逐行读取数据的最简洁的方法。

有一点需要注意:扫描程序将在超过65536个字符的行中出错。如果您知道您的线路长度大于64K,请使用Buffer()方法增加扫描仪的容量:

代码语言:javascript
复制
...
scanner := bufio.NewScanner(file)

const maxCapacity = longLineLen  // your required line length
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)

for scanner.Scan() {
...
票数 774
EN

Stack Overflow用户

发布于 2012-08-31 06:37:48

编辑:从go1.1开始,惯用的解决方案是使用bufio.Scanner

我写了一种方法,可以轻松地读取文件中的每一行。函数的作用是:从底层的bufio.Reader结构中返回一行(sans \n)。

代码语言:javascript
复制
// Readln returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func Readln(r *bufio.Reader) (string, error) {
  var (isPrefix bool = true
       err error = nil
       line, ln []byte
      )
  for isPrefix && err == nil {
      line, isPrefix, err = r.ReadLine()
      ln = append(ln, line...)
  }
  return string(ln),err
}

您可以使用Readln来读取文件中的每一行。下面的代码读取文件中的每一行,并将每一行输出到stdout。

代码语言:javascript
复制
f, err := os.Open(fi)
if err != nil {
    fmt.Printf("error opening file: %v\n",err)
    os.Exit(1)
}
r := bufio.NewReader(f)
s, e := Readln(r)
for e == nil {
    fmt.Println(s)
    s,e = Readln(r)
}

干杯!

票数 60
EN

Stack Overflow用户

发布于 2015-01-21 17:37:06

gist中的示例

代码语言:javascript
复制
func readLine(path string) {
  inFile, err := os.Open(path)
  if err != nil {
     fmt.Println(err.Error() + `: ` + path)
     return
  }
  defer inFile.Close()

  scanner := bufio.NewScanner(inFile)
  for scanner.Scan() {
    fmt.Println(scanner.Text()) // the line
  }
}

但是当有一行比Scanner的缓冲区大时,这会给出一个错误。

当发生这种情况时,我所做的就是使用reader := bufio.NewReader(inFile)创建并使用ch, err := reader.ReadByte()len, err := reader.Read(myBuffer)连接我自己的缓冲区

我使用的另一种方法(用类似于上面的文件替换os.Stdin ),当行很长(isPrefix)时,这种方法会合并,并忽略空行:

代码语言:javascript
复制
func readLines() []string {
  r := bufio.NewReader(os.Stdin)
  bytes := []byte{}
  lines := []string{}
  for {
    line, isPrefix, err := r.ReadLine()
    if err != nil {
      break
    }
    bytes = append(bytes, line...)
    if !isPrefix {
      str := strings.TrimSpace(string(bytes))
      if len(str) > 0 {
        lines = append(lines, str)
        bytes = []byte{}
      }
    }
  }
  if len(bytes) > 0 {
    lines = append(lines, string(bytes))
  }
  return lines
}
票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8757389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档