日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go語言讀取文本文件的三種方式總結_Golang

作者:宇宙之一粟 ? 更新時間: 2023-03-02 編程語言

工作中時不時需要讀取文本,文本文件是最常見的文件類型。

本文將從逐行、逐個單詞和逐個字符三個方法讀取文件:

  • byLine.go
  • byWord.go
  • byCharacter.go

1 逐行讀取文本文件

逐行讀取文件是最為常見的文本文件,也是最為簡單的方式。首先我們需要導入幾個常見的包:

  • bufio:緩存區讀寫文件
  • flag:命令行參數解析
package main

import (
  "bufio"
  "flag"
  "fmt"
  "io"
  "os"
)

func lineByLine(file string) error {

  var err error

  f, err := os.Open(file)
  if err != nil {
    return err
  }

  defer f.Close()

  r := bufio.NewReader(f)
  for {
    line, err := r.ReadString('\n')
    if err == io.EOF {
      break
    } else if err != nil {
      fmt.Printf("error reading file %s", err)
      break
    }
    fmt.Print(line)
  }
  return nil
}

func main() {
  flag.Parse()
  if len(flag.Args()) == 0 {
    fmt.Printf("usage: byLine <file1> [<file2> ...]\n")
    return
  }

  for _, file := range flag.Args() {
    err := lineByLine(file)
    if err != nil {
      fmt.Println(err)
    }
  }
}

代碼解釋:

  • 主要通過?bufio.NewReader()?函數生成一個新的讀取器;
  • 隨后,在?bufio.ReadString()?函數讀取字符,通知該函數持續執行讀取任務,直到碰到該 "\n" 參數,也就是換行符。讀到換行符,執行文本輸出。
  • 如果讀取中斷了,即?err == io.EOF?,退出文件讀取
  • 或者?err != nil, 打印錯誤提示,退出文件執行

main()?函數中首先讀取命令行參數,如果命令行長度為 0,即沒有傳入要讀取的文件,如果此時執行?byLine.go?文件的話就會給出語法提示,如下:

$ go run byLine.go
usage: byLine <file1> [<file2> ...]

我們寫一個測試的文本文件?test.txt, 寫入如下幾行數據,記得在第二行換行(加入空行):

這是第一行
我是第二行

運行如下命令后,結果為:

$ go run byLine.go test.txt
這是第一行
我是第二行

可以使用?cat test.txt?校驗我們的結果的準確性,如下:

$ cat test.txt
這是第一行
我是第二行

2 逐個單詞讀取文本文件

package main

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

func wordByWord(file string) error {
  var err error
  f, err := os.Open(file)
  if err != nil {
    return err
  }

  defer f.Close()
  scanner := bufio.NewScanner(f)
  scanner.Split(bufio.ScanWords)
  var words []string
  for scanner.Scan() {
    words = append(words, scanner.Text())
  }

  for _, word := range words {
    fmt.Println(word)
  }
  return nil
}

func main() {
  flag.Parse()
  if len(flag.Args()) == 0 {
    fmt.Printf("usage: byWord <file1> [file2> ...]\n")
    return
  }

  for _, file := range flag.Args() {
    err := wordByWord(file)
    if err != nil {
      fmt.Println(err)
    }
  }
}

代碼解釋:

  • 其他代碼都和?byLine.go?函數一樣,主要是利用了?bufio?中的 scanner 來掃描單詞,
  • scanner := bufio.NewScanner(file)?用來掃描讀取的文件
  • scanner.Split(bufio.ScanWords)?用來分割單詞
  • 聲明一個單詞字符串列表,將讀取到的每一個單詞放入這個列表中
  • 循環遍歷單詞字符串列表,打印每一個單詞

測試代碼

寫入一個?test.txt?文件:

Hello World
1 2 3

運行代碼,結果顯示:

$ go run byWord.go test.txt
Hello
World
1
2
3

3 逐個字符讀取文本文件

逐個字符讀取文本的使用場景還是很少,除非開發一個文本編輯器。新建一個?byCharacter.go?文件,然后寫入如下代碼:

package main

import (
  "bufio"
  "flag"
  "fmt"
  "io"
  "os"
)

func charByChar(file string) error {

  var err error
  f, err := os.Open(file)
  if err != nil {
    return err
  }

  defer f.Close()

  r := bufio.NewReader(f)
  for {
    line, err := r.ReadString('\n')
    if err == io.EOF {
      break
    } else if err != nil {
      fmt.Printf("error reading file %s", err)
      return err
    }

    for _, x := range line {
      fmt.Println(string(x))
    }
  }
  return nil
}

func main() {
  flag.Parse()
  if len(flag.Args()) == 0 {
    fmt.Printf("usage: byWord <file1> [file2> ...]\n")
    return
  }

  for _, file := range flag.Args() {
    err := charByChar(file)
    if err != nil {
      fmt.Println(err)
    }
  }
}

運行測試用例得出的最后結果為:

$ go run byCharacter.go test.txt?
H
e
l
l
o
?
W
o
r
l
d

總結

本文主要介紹 Go 中的?bufio?包,有些情況下,我們并不只是需要讀取整個一大段文件,所以需要把文件通過某種方式讀取,并介紹了 Go 讀取文本文件中的三種方法:

  • 逐行讀取文本文件?byLine.go
  • 逐個單詞讀取文本文件?byWord.go
  • 逐個字符讀取文本文件?byCharacter.go

其實還有更多讀取文本文件的方法,比如通過逗號讀取、讀取特定數據量的文本,這些方法留到后文再作介紹

原文鏈接:https://segmentfault.com/a/1190000043291434

欄目分類
最近更新