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("%#Un", 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。