持久化 Reader() 对象

Persistent Reader() object

在 Go 中,我正在尝试创建一个函数来读取和处理下一行输入:

// Read a string of hex from stdin and parse to an array of bytes
func ReadHex() []byte {
    r := bufio.NewReader(os.Stdin)
    t, _ := r.ReadString('\n')
    data, _ := hex.DecodeString(strings.TrimSpace(t))
    return data
}

不幸的是,这只在第一次调用时有效。它捕获第一行,但无法捕获通过标准输入管道传输的后续行。

我怀疑,如果在每个后续调用中使用相同的持久性 bufio.Reader() 对象,它会起作用,但如果不在每个函数调用中手动传递它,我无法实现这一点。

  1. 是的,试试 this:
package main

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

func ReadFunc() func() []byte {
    r := bufio.NewReader(os.Stdin)
    return func() []byte {
        t, err := r.ReadString('\n')
        if err != nil {
            log.Fatal(err)
        }
        data, err := hex.DecodeString(strings.TrimSpace(t))
        if err != nil {
            log.Fatal(err)
        }
        return data
    }
}

func main() {
    r, w, err := os.Pipe()
    if err != nil {
        log.Fatal(err)
    }
    os.Stdin = r
    w.Write([]byte(`ffff
    cafebabe
    ff
    `))
    w.Close()

    ReadHex := ReadFunc()

    fmt.Println(ReadHex())
    fmt.Println(ReadHex())
    fmt.Println(ReadHex())
}

输出:

[255 255]
[202 254 186 190]
[255]

  1. 使用 struct,尝试 this:
package main

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

// InputReader struct
type InputReader struct {
    bufio.Reader
}

// New creates an InputReader
func New(rd io.Reader) *InputReader {
    return &InputReader{Reader: *bufio.NewReader(rd)}
}

// ReadHex returns a string of hex from stdin and parse to an array of bytes
func (r *InputReader) ReadHex() []byte {
    t, err := r.ReadString('\n')
    if err != nil {
        log.Fatal(err)
    }
    data, err := hex.DecodeString(strings.TrimSpace(t))
    if err != nil {
        log.Fatal(err)
    }
    return data
}

func main() {
    r, w, err := os.Pipe()
    if err != nil {
        log.Fatal(err)
    }
    os.Stdin = r
    w.Write([]byte(`ffff
    cafebabe
    ff
    `))
    w.Close()

    rdr := New(os.Stdin)
    fmt.Println(rdr.ReadHex())
    fmt.Println(rdr.ReadHex())
    fmt.Println(rdr.ReadHex())
}