簡體   English   中英

GoLang 鏈接 io.Reader

[英]GoLang chaining io.Reader

我正在嘗試實現一個代理模式來鏈接 io.Reader 上的轉換,以便有效地處理字節塊。

  1. 我們不能在接收器上使用指針,所以我的解決方案似乎不是很有效

  2. 下面的代碼說“過程花費太長時間”

完整示例位於: https : //play.golang.org/p/KhM0VXLq4CO

b := bytes.NewBufferString(text)
t := transformReaderHandler(*b)
readByChunk(t)

type transformReaderHandler bytes.Buffer

func (t transformReaderHandler) Read(p []byte) (n int, err error) {
    n, err = (*bytes.Buffer)(&t).Read(p)
    //if n > 0 {
    //  Do Something on the chunk
    //}
    return
}

你有更高效(內存高效、計算高效)的解決方案嗎?

為什么這段代碼不起作用?

編輯:@svsd 解決方案的實現: https : //play.golang.org/p/VUpJcyKLB6D

package main

import (
    "io"
    "fmt"
    "bytes"
)

const text = "Reaaaaally long and complex text to read in chunk"

func main() {
    b := bytes.NewBufferString(text)

    t := (*transformReaderHandler)(b)

    readByChunk(t)
}

type transformReaderHandler bytes.Buffer

func (t *transformReaderHandler) Read(p []byte) (n int, err error) {
    n, err = (*bytes.Buffer)(t).Read(p)
    if n > 0 {
        p[0] = 'X'
    }
    return
}

func readByChunk(r io.Reader) {
    var p = make([]byte, 4)

    for {
        n, err := r.Read(p)
        if err == io.EOF {
            break
        }
        fmt.Println(string(p[:n]))
    }
}

每次在transformReaderHandler上調用Read您都在復制bytes.Buffer值,因此您永遠無法通過緩沖區。 您必須使用*bytes.Buffer指針來避免此副本。

在您的transformReaderHandler嵌入緩沖區(或將其添加為命名字段),以便您可以根據需要調用委托Read方法。

type transformReaderHandler struct {
    *bytes.Buffer
}

func (t *transformReaderHandler) Read(p []byte) (n int, err error) {
    n, err = t.Buffer.Read(p)
    //if n > 0 {
    //  Do Something
    //}
    return
}

https://play.golang.org/p/npZQ4Tz0hhv

下面的代碼說“過程花費太長時間”

為什么這段代碼不起作用?

transformReaderHandler.Read()方法中,您有一個值接收器。 這意味着每次調用Read() ,它都會獲取調用它的實例的副本 然后,當您調用(*bytes.Buffer)(&t).Read(p) ,它會修改該實例的內部狀態,以便下次讀取時,它會從之前讀取的點之后讀取。

現在因為實例是副本,所以在方法退出后被丟棄,原始實例保持不變。 因此,每次調用Read()bytes.Buffer.Read()僅讀取前幾個字節。 為了證明這一點,在調用Read()之后在readByChunk()添加一條語句fmt.Println("n=", n, "err=", err) Read()

為了快速檢查這確實是由於值接收器,您可以使用指針接收器定義transformReaderHandler.Read()並將t存儲為t = (*transformReaderHandler)(b) 我會讓你檢查它的作用。 (編輯:涉及嵌入的正確解決方案在評論中)

你有更高效(內存高效、計算高效)的解決方案嗎?

如果您只是在尋找緩沖 IO 以提高讀取效率,請查看bufio.NewReader() 如果這還不夠,您可以從中io.Reader靈感並環繞一個io.Reader接口,而不是環繞一個bytes.Buffer實例。

暫無
暫無

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

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