天天看點

Golang 中的 io 包詳解(四):單位元組操作接口

作者:路多辛

io.ByteReader

type ByteReader interface {
	ReadByte() (byte, error)
}           

定義了一個基本方法 ReadByte,用于讀取資料源中的單個位元組,如果沒有位元組可讀,傳回非 nil 的錯誤。

标準庫中的 bufio.Reader 實作了該接口,從一個 io.Reader 中讀取并提供帶緩存的讀取方法,簡單示例如下:

package main

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

func main() {
	data := "abc123"
	reader := bufio.NewReader(strings.NewReader(data))

	for {
		c, err := reader.ReadByte()
		if err != nil {
			break
		}
		fmt.Print(string(c))
	}
}           

io.ByteScanner

type ByteScanner interface {
	ByteReader
	UnreadByte() error
}           

是 io.ByteReader 接口的擴充,提供了一個額外的方法:UnreadByte,UnreadByte方法讓下一次調用 ReadByte 時傳回之前調用 ReadByte 時傳回的同一個位元組。

io.ByteWriter

// ByteWriter is the interface that wraps the WriteByte method.
type ByteWriter interface {
	WriteByte(c byte) error
}           

定義了一個基本方法 ReadByte,用于向資料源中寫入單個位元組的能力,

标準庫中的 bufio.Writer 實作了該接口,從位元組序列中構造并提供緩沖輸出,簡單示例如下:

package main

import (
	"bufio"
	"bytes"
	"fmt"
)

func main() {
	buf := new(bytes.Buffer)
	writer := bufio.NewWriter(buf)

	for _, c := range "abc123" {
		err := writer.WriteByte(byte(c))
		if err != nil {
			panic(err)
		}
	}

	writer.Flush()
	fmt.Println(buf.String())
}           

io.RuneReader

type RuneReader interface {
	ReadRune() (r rune, size int, err error)
}           

用于從字元流中讀取 Unicode 碼點(Rune),定義了一個基本方法 ReadRune,接受一個參數類型為 rune 的指針,并傳回讀取的 Rune 以及錯誤類型。

io.RuneReader 通常與 bufio.Reader 一起使用,用于建構高效的文本讀取器。例如如下示例,使用 bufio.Reader 讀取一個檔案并逐行解析其中的 Unicode 碼點:

package main

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

func main() {
	file, _ := os.Open("file.txt")
	defer file.Close()

	reader := bufio.NewReader(file)

	for {
		r, _, err := reader.ReadRune()
		if err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}
		if r == '\n' {
			fmt.Println()
		} else {
			fmt.Print(r)
		}
	}
}           

io.RuneScanner

type RuneScanner interface {
	RuneReader
	UnreadRune() error
}           

擴充了 io.RuneReader 接口,添加了一個名為 UnreadRune 的方法,用于撤消最近讀取的 Rune,并使下一次讀取的時候再次傳回該 Rune。簡單示例如下:

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	for {
		if ok := scanner.Scan(); !ok {
			break
		}

		str := scanner.Text()
		reader := strings.NewReader(str)

		for {
			runeScanner := bufio.NewReader(reader)
			r, _, err := runeScanner.ReadRune()
			if err != nil {
				if err == io.EOF {
					break
				}
				log.Fatal(err)
			}
			fmt.Printf("%#U\n", r)
		}
	}
}           

使用 bufio.Scanner 從控制台讀取每一行輸入,然後将每一行轉換為一個 strings.Reader,并将其傳遞給 bufio.NewReader 來掃描 Rune。

io.StringWriter

// StringWriter is the interface that wraps the WriteString method.
type StringWriter interface {
	WriteString(s string) (n int, err error)
}           

定義了一個基本方法 WriteString,用來将資料寫入一個字元串。簡單示例如下:

package main

import (
	"fmt"
	"io"
	"strings"
)

func main() {
	var builder strings.Builder

	writer := io.StringWriter(&builder)

	writer.WriteString("Hello, ")
	writer.WriteString("World!")

	result := builder.String()

	fmt.Println(result) // 輸出:Hello, World!
}
           

首先建立了一個 strings.Builder,然後使用 io.StringWriter 将 builder 轉換為一個 io.Writer,最後使用 builder.String 将最終結果轉換為一個 string。

繼續閱讀