【问题标题】:Create an io.ReaderAt from io.Reader从 io.Reader 创建一个 io.ReaderAt
【发布时间】:2017-03-05 10:12:15
【问题描述】:

是否可以从io.Reader 的实现创建io.ReaderAt 的实现,而无需先读入[]bytestring

【问题讨论】:

  • 这个限制意味着你不能向后搜索也不能重新阅读任何阅读部分。可以吗?
  • 嘿蒂姆,是的,那很好。最终目标是 SectionReader,因此无需向后阅读,也无需重新阅读。

标签: go interface


【解决方案1】:

如下所示。注意bytes.Reader 实现ReadAt(...) 方法/函数:https://golang.org/pkg/bytes/#Reader.ReadAt。所以bytes.NewReader 这行基本上就是你要找的。​​p>

获取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`

【讨论】:

    【解决方案2】:

    是的,这是可能的。正如我在上面的评论中提到的,实现的局限性在于您不能向后搜索,也不能重新阅读已经阅读过的部分。

    这是一个示例实现:

    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"
    

    【讨论】:

    • 这太棒了!谢谢:)
    • 第二次返回应该是return written, err 而不是return 0, err
    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2012-01-30
    • 2013-01-24
    • 2014-12-26
    • 1970-01-01
    相关资源
    最近更新 更多