簡體   English   中英

從io.Reader創建一個io.ReaderAt

[英]Create an io.ReaderAt from io.Reader

是否有io.ReaderAt的實現,可以從io.Reader的實現創建而不首先被讀入[]bytestring

是的,這是可能的。 正如我在上面的評論中所提到的,實現是有限的,因為你不能向后搜索,也不能重新閱讀已經閱讀過的部分。

這是一個示例實現:

type unbufferedReaderAt struct {
    R io.Reader
    N int64
}

func NewUnbufferedReaderAt(r io.Reader) io.ReaderAt {
    return &unbufferedReaderAt{R: r}
}

func (u *unbufferedReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
    if off < u.N {
        return 0, errors.New("invalid offset")
    }
    diff := off - u.N
    written, err := io.CopyN(ioutil.Discard, u.R, diff)
    u.N += written
    if err != nil {
        return 0, err
    }

    n, err = u.R.Read(p)
    u.N += int64(n)
    return
}

用法示例:

s := strings.NewReader("hello world")

var b [5]byte
ura := NewUnbufferedReaderAt(s)
if _, err := ura.ReadAt(b[:], 0); err != nil {
    panic(err)
}
fmt.Printf("%s\n", b[:]) // prints "hello"

/*
if _, err := ura.ReadAt(b[:], 0); err != nil {
    panic(err) // panics
}
fmt.Printf("%s\n", b[:])
*/

if _, err := ura.ReadAt(b[:], 6); err != nil {
    panic(err)
}
fmt.Printf("%s\n", b[:]) // prints "world"

像下面這樣的東西。 注意bytes.Reader實現ReadAt(...)方法/函數: httpsReadAt(...) 所以行bytes.NewReader根本就是你要找的東西。

獲取bytes.Reader

var ioReader io.Reader
...
buff := bytes.NewBuffer([]byte{})
size, err := io.Copy(buff, ioReader)
if err != nil {
    return err
}

reader := bytes.NewReader(buff.Bytes())
// Do something with `reader`

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM