英文:
byte[] channel usage
问题
我正在收到一个REST命令,并希望对其主体进行哈希函数计算。
为此,我使用io.TeeReader(request.Body, &writerToHash)
读取主体,其中我传递了自己实现的实现了io.Writer接口的类:
func (self *WriterToHash) Write(p []byte) (n int, err error) {
n = len(p)
fmt.Println("WriterToHash len=%v, buff=%v", n, p) //PRINT 1
self.BodyChannel <- p
return n, nil
}
BodyChannel
被定义为:BodyChannel chan []byte
我按以下方式使用这个类:
writerToHash := sisutils.WriterToHash{
BodyChannel: make(chan []byte, 1024)
}
writerToHash.StartListen()
reqnew, _ := http.NewRequest("PUT", url, io.TeeReader(request.Body, &writerToHash))
监听部分:
func (wth *WriterToHash) StartListen() {
wth.OutChannel = make(chan []byte, 1000)
go func(self *WriterToHash) {
done := int64(0)
h := sha1.New()
for done < MessageSize {
buff := <-self.BodyChannel
done += int64(len(buff))
DPrint(5, "AccamulateSha1 Done=: %v, buff=%v", done, buff) //PRINT 2
actually_write, err := h.Write(buff)
if err != nil || actually_write != len(buff) {
log.Println("Error in sha write:" + err.Error())
break
}
}
bs := h.Sum(nil)
self.OutChannel <- bs
}(wth)
}
我发送的消息大小为1000字节。在调试模式下,消息总是以相同的方式分割:1字节,999字节 - 我通过PRINT 1看到了这一点。在这种情况下一切正常。
问题是当消息在Write函数中分成多个部分时。在PRINT 1中我看到:
[第一个字节]:a
[接下来的约450字节]:b,c,d,...
[最后的约550字节]:w,x,y,...
但在PRINT 2中我看到不同的情况:
[第一个字节]:a
[约450字节,但从最后一部分开始]:w,x,y...
[最后的约550字节]:w,x,y...
我实际上两次获取了最后一部分,但大小不同。
英文:
I am getting a REST command, and want to calculate hash function on it's body.
To do so I read the body using io.TeeReader(request.Body, &writerToHash)
where I pass my own class that implements io.Writer:
func (self *WriterToHash) Write(p []byte) (n int, err error) {
n=len(p)
fmt.println("WriterToHash len=%v, buff=%v", n, p) //PRINT 1
self.BodyChannel <- p
return n, nil
}
The BodyChannel
is defined: BodyChannel chan []byte
I use this class as follows:
writerToHash := sisutils.WriterToHash{
BodyChannel:make(chan []byte, 1024)
}
writerToHash.StartListen()
reqnew, _ := http.NewRequest("PUT", url, io.TeeReader(request.Body, &writerToHash))
Listening part:
func (wth *WriterToHash) StartListen() {
wth.OutChannel = make(chan []byte, 1000)
go func (self *WriterToHash) {
done := int64(0)
h := sha1.New()
for done < MessageSize{
buff := <- self.BodyChannel
done += int64(len(buff))
DPrint(5, "AccamulateSha1 Done=: %v, buff=%v", done, buff) //PRINT 2
actually_write, err := h.Write(buff)
if err != nil || actually_write != len(buff) {
log.Println("Error in sha write:" + err.Error())
break
}
}
bs := h.Sum(nil)
self.OutChannel <- bs
}(wth)
}
I send messages of 1000 bytes. In debug mode the message is always split in the same way: 1 byte, 999 bytes - I see it using PRINT 1. In this case everythong works fine.
The problem is that when the message is split to more parts in the Write function. In this case I see in PRINT1:
[first byte] : a
[next ~450 bytes] : b,c,d,...
[last ~550 bytes] : w,x,y,...
but in PRINT 2 I see different picture:
[first byte] : a
[ ~450 bytes but starting where last part starts] : w,x,y...
[last ~550 bytes] : w,x,y,...
I actually get the last past twice but not in the same size.
答案1
得分: 6
从io.Writer
文档中:
> Write不能修改切片数据,即使是临时的。实现不能保留p。
你不能存储或重用传递给Write方法的切片。如果你想在其他地方使用这些数据,你需要对其进行复制。
func (self *WriterToHash) Write(p []byte) (n int, err error) {
b := make([]byte, len(p))
copy(b, p)
fmt.println("WriterToHash len=%d, buff=%v", len(p), b)
self.BodyChannel <- b
return len(p), nil
}
英文:
From the io.Writer
documentation:
> Write must not modify the slice data, even temporarily. Implementations must not retain p
You can't store or reuse the slice being passed to your Write method. If you want to use that data elsewhere, you need to make a copy of it
func (self *WriterToHash) Write(p []byte) (n int, err error) {
b := make([]byte, len(p))
copy(b, p)
fmt.println("WriterToHash len=%d, buff=%v", len(p), b)
self.BodyChannel <- b
return len(p), nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论