当我尝试在Golang中解码一个gob时,我遇到了”extra data in buffer”错误。

huangapple go评论86阅读模式
英文:

I'm getting "extra data in buffer" error when trying to decode a gob in golang

问题

我正在流上进行多个对象的编码和发送。我按照下面的代码进行解码,保持连接打开。在解码第一个对象之后,我得到了“缓冲区中的额外数据”错误。

func handleAggregatorConnection(conn net.Conn) {
    var connectionNumber = connectionCount
    connectionCount += 1
    log.Println("connection event: starting handle aggregator connection")

    dec := gob.NewDecoder(conn)

    var colorArrays map[string][]string
    colorArrayValue := &colorArrays

    var i P
    ai := &i

    for {
        //err := dec.Decode(colorArrayValue)
        err := dec.Decode(ai)
        if err == nil {
            receivedColorResultFromAggregator = true
            //log.Printf("received : %+v", colorArrayValue)
            log.Println("received:", i)
            aggregatorResultMap[connectionNumber] = *colorArrayValue
            log.Println("control server: received object from aggregator ", aggregatorResultMap)
        } else if err == io.EOF {
            log.Println("reached end of stream while" +
                "listening to aggregator")
            delete(aggregatorResultMap, connectionNumber)
            break
        } else {
            log.Println("error decoding:", err)
            break
        }
    }
    log.Println("connection event: closing aggregator connection")
    conn.Close()
}
英文:

I'm encoding and sending multiple objects on a stream. I decode them as show in code below, keeping the connection open. I'm getting "extra data in buffer" error on the decode of all objects after the first.

func handleAggregatorConnection(conn net.Conn) {
        var connectionNumber = connectionCount
        connectionCount += 1
        log.Println("connection event: starting handle aggregator connection")


        dec := gob.NewDecoder(conn)

        var colorArrays map[string][]string
        colorArrayValue := &colorArrays

        var i P
        ai := &i


        for {
                //err := dec.Decode(colorArrayValue)
                err := dec.Decode(ai)
                if err == nil {
                        receivedColorResultFromAggregator = true
                        //log.Printf("received : %+v", colorArrayValue)
                        log.Println("received:", i)
                        aggregatorResultMap[connectionNumber] = *colorArrayValue
                        log.Println("control server: received object from aggregator ", aggregatorR\
esultMap)
                } else if err == io.EOF {
                        log.Println("reached end of stream while" +
                                "listening to aggregator")
                        delete(aggregatorResultMap, connectionNumber)
                        break
                } else {
                        log.Println("error decoding:", err)
                        break
                }
        }
        log.Println("connection event: closing aggregator connection")
        conn.Close()
}

答案1

得分: 4

我不同意你的回答,我自己用以下方式编写了一个读取器:

func GetAll(db string) ([]*Record, error) {
    r := []*Record{}

    f, err := os.OpenFile(db, os.O_RDONLY, 0644)
    if err != nil {
        return nil, err
    }

    var rr error
    gdec := gob.NewDecoder(f)
    for rr != io.EOF {
        rec := Record{}
        rr = gdec.Decode(&rec)
        if rr != nil {
            continue
        }
        r = append(r, &rec)
    }

    return r, nil
}

它按预期工作。

在我看来,如果出现错误,你不应该"break",而是应该继续读取数据。

英文:

I don't agree your answer, I did myself a gobs reader that way:

func GetAll(db string) ([]*Record, error) {
    r := []*Record{}

	f, err := os.OpenFile(db, os.O_RDONLY, 0644)
    if err != nil {
	    return nil, err
    }

    var rr error
    gdec := gob.NewDecoder(f)
    for rr != io.EOF {
	    rec := Record{}
	    rr = gdec.Decode(&rec)
	    if rr != nil {
	    	continue
	    }
	    r = append(r, &rec)
    }

    return r, nil
}

And it works as exepected.

IMHO, you should not "break" if an error appear and continue to read data.

答案2

得分: -1

回答我的问题:为每个解码操作创建一个新的解码器可以使其正常工作。

func handleAggregatorConnection(conn net.Conn) {
    var connectionNumber = connectionCount
    connectionCount += 1
    log.Println("连接事件:开始处理聚合器连接")

    for {

        dec := gob.NewDecoder(conn)

        var colorArrays map[string][]string
        colorArrayValue := &colorArrays

        var i P
        ai := &i



        //err := dec.Decode(colorArrayValue)
        err := dec.Decode(ai)
        if err == nil {
            receivedColorResultFromAggregator = true
            //log.Printf("received : %+v", colorArrayValue)
            log.Println("接收到:", i)
            aggregatorResultMap[connectionNumber] = *colorArrayValue
            log.Println("控制服务器:从聚合器接收到对象", aggregatorResultMap)
        } else if err == io.EOF {
            log.Println("在监听聚合器时到达流的末尾")
            delete(aggregatorResultMap, connectionNumber)
            break
        } else {
            log.Println("解码错误:", err)
            break
        }
    }
    log.Println("连接事件:关闭聚合器连接")
    conn.Close()
}

注意:我已经将代码中的引号从"替换为实际的引号。

英文:

Answering my own question: creating a new decoder for each decode operation makes it work.

func handleAggregatorConnection(conn net.Conn) {
        var connectionNumber = connectionCount
        connectionCount += 1
        log.Println("connection event: starting handle aggregator connection")

        for {

                dec := gob.NewDecoder(conn)

                var colorArrays map[string][]string
                colorArrayValue := &colorArrays

                var i P
                ai := &i



                //err := dec.Decode(colorArrayValue)
                err := dec.Decode(ai)
                if err == nil {
                        receivedColorResultFromAggregator = true
                        //log.Printf("received : %+v", colorArrayValue)
                        log.Println("received:", i)
                        aggregatorResultMap[connectionNumber] = *colorArrayValue
                        log.Println("control server: received object from aggregator ", aggregatorR\
esultMap)
                } else if err == io.EOF {
                        log.Println("reached end of stream while" +
                                "listening to aggregator")
                        delete(aggregatorResultMap, connectionNumber)
                        break
                } else {
                        log.Println("error decoding:", err)
                        break
                }
        }
        log.Println("connection event: closing aggregator connection")
        conn.Close()
}

huangapple
  • 本文由 发表于 2017年8月10日 09:44:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/45603132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定