英文:
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()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论