Go 語言讀取文件的幾種方式

前言

這篇文章將討論如何在 Golang 中讀取文件。我們將使用以下包來處理這些文件。

整個文件讀取

我們可以很容易地一次性讀取整個文件並將其存儲在一個變量中。但請記住,我們不應該對大文件這樣做。我們將使用ioutil.ReadFile() 函數來讀取文件並將文件的內容存儲在一個變量中。

首先,讓我們在我們程序所在的同一目錄下存儲一個文件。因此,我們的文件夾結構將是下面這樣的。

___ 
| 
|_ _ _ _ ilovego.txt | 
|_ _ _ _ main.go

我們在 main.go 函數中寫入如下的內容:

package main

import (
 "fmt"
 "io/ioutil"
 "log"
)

func main() {

 content, err := ioutil.ReadFile("ilovego.txt")

 if err != nil {
  log.Fatal(err)
 }

 fmt.Println(string(content))
}

但首先,讓我們討論一下 ReadFile() 函數的情況:

內部 ReadFile 函數實現如下:

func ReadFile(filename string) ([]byte, error) {
    return os.ReadFile(filename)
}

現在,讓我們回到我們的程序:

然後新建一個 ilovego.txt 文件,寫入如下內容:

I Love Golang,
This is One of the Best Languages on the World!

最後,執行上述代碼,可以看到如下輸出:

$ go run main.go
I Love Golang, 
This is One of the Best Languages on the World!

按行讀取

Scanner 掃描器提供了一個方便的接口來讀取數據,比如一個由新行分隔的文本行組成的文件。它通過標記來讀取數據;Split 函數定義了標記。默認情況下,該函數將數據分成幾行,並剝離了行端。

package main

import (
 "fmt"
 // "io/ioutil"
 "bufio"
 "log"
 "os"
)

func main() {

 // opening the file using Open function
 f, err := os.Open("ilovego.txt")

 if err != nil {
  log.Fatal(err)
 }

 defer f.Close()

 // create a scanner for the file
 scanner := bufio.NewScanner(f)

 // loop through the scanner until it return fasle
 for scanner.Scan() {

  fmt.Println(scanner.Text())
 }

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

執行程序,結果如下:

逐個單詞讀取

我們還可以通過逐個單詞來讀取文件:

package main

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

func main() {

 f, err := os.Open("ilovego.txt")

 if err != nil {
  fmt.Println(err)
 }

 defer f.Close()

 scanner := bufio.NewScanner(f)
 scanner.Split(bufio.ScanWords)

 for scanner.Scan() {

  fmt.Println(scanner.Text())
 }

 if err := scanner.Err(); err != nil {
  fmt.Println(err)
 }
}

運行代碼:

$ go run main.go
I
Love
Golang,
This
is
One
of
the
Best
Languages
on
the
World!

以數據塊的形式讀取文件

一次性讀取整個文件似乎是一種簡單的方法,但有時我們需要從內存管理的角度使我們的程序得到一些優化。Golang 提供了一種分塊讀取文件的方法,而不是整個或甚至逐行讀取。因爲如果一行的大小太大,逐行讀取也可能是低效的。

package main

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

func main() {

 f, err := os.Open("ilovego.txt")

 if err != nil {
  log.Fatal(err)
 }

 defer f.Close()

 reader := bufio.NewReader(f)
 buf := make([]byte, 16)

 for {
                // reading a file upto buffer
  n, err := reader.Read(buf)

  if err != nil {

   if err != io.EOF {

    log.Fatal(err)
   }

   break
  }

  fmt.Print(string(buf[0:n]))
 }

 fmt.Println()
}

二進制讀取

hex 包實現了十六進制的編碼和解碼。

package main

import (
 "bufio"
 "encoding/hex"
 "fmt"
 "io"
 "log"
 "os"
)

func main() {

 f, err := os.Open("sid.jpg")

 if err != nil {
  log.Fatal(err)
 }

 defer f.Close()

 reader := bufio.NewReader(f)
 buf := make([]byte, 256)

 for {
  _, err := reader.Read(buf)

  if err != nil {
   if err != io.EOF {
    fmt.Println(err)
   }
   break
  }

  fmt.Printf("%s", hex.Dump(buf))
 }
}

總結

本文介紹了 Go 語言讀取文件的幾種方式,ioutil.ReadFile 函數將整個文件讀成一個字符串。這個函數很方便,但不應該用於非常大的文件。希望能對你有所幫助!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/4gqRsDkDDSaY-mUUwVmp0Q