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

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


当前回答

在Go 1.16的新版本中,我们可以使用包嵌入来读取文件内容,如下所示。

package main

import _"embed"


func main() {
    //go:embed "hello.txt"
    var s string
    print(s)

    //go:embed "hello.txt"
    var b []byte
    print(string(b))

    //go:embed hello.txt
    var f embed.FS
    data, _ := f.ReadFile("hello.txt")
    print(string(data))
}

欲了解更多详情,请访问https://tip.golang.org/pkg/embed/ 和 https://golangtutorial.dev/tips/embed-files-in-go/

其他回答

扫描*功能是伟大的用户在这里。下面是go-lang docs中稍微修改过的单词扫描器示例,用于扫描文件中的行。

package main

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

func main() {
    // An artificial input source.
    const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n"
    scanner := bufio.NewScanner(strings.NewReader(input))
    // Set the split function for the scanning operation.
    scanner.Split(bufio.ScanLines)
    // Count the lines.
    count := 0
    for scanner.Scan() {
        fmt.Println(scanner.Text())
        count++
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading input:", err)
    }
    fmt.Printf("%d\n", count)
}

在下面的代码中,我从CLI中读取兴趣,直到用户按下enter键,我使用Readline:

interests := make([]string, 1)
r := bufio.NewReader(os.Stdin)
for true {
    fmt.Print("Give me an interest:")
    t, _, _ := r.ReadLine()
    interests = append(interests, string(t))
    if len(t) == 0 {
        break;
    }
}
fmt.Println(interests)

有两种常见的逐行读取文件的方法。

使用bufio。扫描仪 使用ReadString / ReadBytes /……在bufio。读者

在我的测试案例中,~250MB, ~2,500,000行,bufio。Scanner(使用时间:0.395491384s)比bufio.Reader快。ReadString (time_used: 0.446867622 s)。

源代码:https://github.com/xpzouying/go-practice/tree/master/read_file_line_by_line

使用bufio读取文件。扫描仪,

func scanFile() {
    f, err := os.OpenFile(logfile, os.O_RDONLY, os.ModePerm)
    if err != nil {
        log.Fatalf("open file error: %v", err)
        return
    }
    defer f.Close()

    sc := bufio.NewScanner(f)
    for sc.Scan() {
        _ = sc.Text()  // GET the line string
    }
    if err := sc.Err(); err != nil {
        log.Fatalf("scan file error: %v", err)
        return
    }
}

使用bufio读取文件。读者,

func readFileLines() {
    f, err := os.OpenFile(logfile, os.O_RDONLY, os.ModePerm)
    if err != nil {
        log.Fatalf("open file error: %v", err)
        return
    }
    defer f.Close()

    rd := bufio.NewReader(f)
    for {
        line, err := rd.ReadString('\n')
        if err != nil {
            if err == io.EOF {
                break
            }

            log.Fatalf("read file line error: %v", err)
            return
        }
        _ = line  // GET the line string
    }
}

你也可以使用带\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
    }
  }

bufio.Reader.ReadLine()工作得很好。但是如果你想通过字符串读取每一行,尝试使用ReadString('\n')。它不需要重新发明轮子。