我找不到文件。围棋中的ReadLine函数。

如何一行一行地读取文件?


当前回答

你也可以使用带\n的ReadString作为分隔符:

  f, err := os.Open(filename)
  if err != nil {
    fmt.Println("error opening file ", err)
    os.Exit(1)
  }
  defer f.Close()
  r := bufio.NewReader(f)
  for {
    path, err := r.ReadString(10) // 0x0A separator = newline
    if err == io.EOF {
      // do something here
      break
    } else if err != nil {
      return err // if you return error
    }
  }

其他回答

另一种方法是使用io/ioutil和strings库来读取整个文件的字节,将它们转换为字符串,并使用“\n”(换行符)字符作为分隔符来分割它们,例如:

import (
    "io/ioutil"
    "strings"
)

func main() {
    bytesRead, _ := ioutil.ReadFile("something.txt")
    fileContent := string(bytesRead)
    lines := strings.Split(fileContent, "\n")
}

从技术上讲,您不是逐行读取文件,但是您可以使用这种技术解析每一行。此方法适用于较小的文件。如果您试图解析一个大型文件,请使用逐行读取的技术之一。

你也可以使用带\n的ReadString作为分隔符:

  f, err := os.Open(filename)
  if err != nil {
    fmt.Println("error opening file ", err)
    os.Exit(1)
  }
  defer f.Close()
  r := bufio.NewReader(f)
  for {
    path, err := r.ReadString(10) // 0x0A separator = newline
    if err == io.EOF {
      // do something here
      break
    } else if err != nil {
      return err // if you return error
    }
  }

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

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个字符时,Scanner将出错。如果你知道你的行长大于64K,使用Buffer()方法来增加扫描仪的容量:

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

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

for scanner.Scan() {
...

注意:在Go的早期版本中,接受的答案是正确的。见投票最高的答案包含了实现这一目标的最新惯用方法。

包bufio中有一个ReadLine函数。

请注意,如果该行不适合读缓冲区,该函数将返回一个不完整的行。如果你想通过对函数的一次调用来读取程序中的整行,你需要将ReadLine函数封装到你自己的函数中,该函数在for循环中调用ReadLine。

bufio.ReadString('\n')并不完全等同于ReadLine,因为ReadString无法处理文件的最后一行不以换行符结束的情况。

这个要点的例子

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
  }
}

但是当有一行比扫描器的缓冲区大时,就会出现错误。

当发生这种情况时,我所做的是使用reader:= bufio.NewReader(inFile)创建和concat我自己的缓冲区使用ch, err:= reader. readbyte()或len, err:= reader. read (myBuffer)

我用(替换os)的另一种方法。Stdin with file like above),当行很长(isPrefix)时,它会连接并忽略空行:


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
}