天天看點

go語言讀取檔案

作者:幹飯人小羽
go語言讀取檔案

前言

這篇文章将讨論如何在 Golang 中讀取檔案。我們将使用以下包來處理這些檔案。

  • os 包提供了一個獨立于平台的接口來執行操作級操作。
  • IOutil 軟體包提供了易于使用的實用程式函數來處理檔案,而無需了解太多内部實作。
  • bufio 包實作了緩沖 IO,這有助于我們提高輸入和輸出操作的性能和吞吐量。
  • log 包實作一個簡單的日志記錄包。我們将在整個程式中使用它。我們将在程式中使用日志包的 Fatal() 函數。

整個檔案讀取

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

首先,讓我們在我們程式所在的同一目錄下存儲一個檔案。是以,我們的檔案夾結構将是下面這樣的。

css複制代碼___ 
| 
|_ _ _ _ ilovego.txt | 
|_ _ _ _ main.go
           

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

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() 函數的情況:

  • 定義:方法聲明 func ReadFile(filename string) ([]byte, error)
  • 功能:讀取路徑被傳入函數參數的檔案,并傳回檔案的内容。在内部使用 os.ReadFile(fileName) 方法
  • 傳回:在一個位元組數組中傳回檔案的内容和錯誤。一個成功的調用将傳回 err == nil

内部 ReadFile 函數實作如下:

go複制代碼func ReadFile(filename string) ([]byte, error) {
    return os.ReadFile(filename)
}
           

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

  • ioutil.ReadFile("readthisfile.txt") 傳回一個 byteArray 和一個 err。我們将byteArray 存儲在 "content "變量中,錯誤存儲在 " err "變量中。
  • 然後我們放置了一個 if 條件,如果 err 值不為 nil,我們将使用 log.Fatal() 函數列印錯誤 err 。記住,Fatal() 函數等同于 Print() 函數,然後調用 os.Exit(1) 。
  • 最後,我們将使用 fmt.Println() 函數列印檔案的内容。 我們不能簡單地列印 content 變量,因為它是一個位元組數組,我們需要将它轉換為字元串: string(content)

然後建立一個 ilovego.txt 檔案,寫入如下内容:

csharp複制代碼I Love Golang,
This is One of the Best Languages on the World!
           

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

csharp複制代碼$ go run main.go
I Love Golang, 
This is One of the Best Languages on the World!
           

按行讀取

Scanner 掃描器提供了一個友善的接口來讀取資料,比如一個由新行分隔的文本行組成的檔案。它通過标記來讀取資料;Split 函數定義了标記。預設情況下,該函數将資料分成幾行,并剝離了行端。

go複制代碼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)
	}
}

           
  • os.Open() 打開參數中傳遞的檔案。如果在打開檔案時遇到任何錯誤,它将傳回同樣的錯誤。否則,錯誤将是 nil。
  • 然後,我們使用掃描器來讀取檔案,并逐行掃描,直到檔案内容結束。
  • 最後,我們要關閉該檔案。

執行程式,結果如下:

go語言讀取檔案

逐個單詞讀取

我們還可以通過逐個單詞來讀取檔案:

go複制代碼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)
	}
}
           

運作代碼:

csharp複制代碼$ go run main.go
I
Love
Golang,
This
is
One
of
the
Best
Languages
on
the
World!
           

以資料塊的形式讀取檔案

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

go複制代碼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 包實作了十六進制的編碼和解碼。

go複制代碼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 函數将整個檔案讀成一個字元串。這個函數很友善,但不應該用于非常大的檔案。希望能對你有所幫助!

連結:https://juejin.cn/post/7218564871831240760

繼續閱讀