golangチャンネルで新しく説明できない奇妙な動作があります。 私はRESTコマンドを取得しており、その本体にハッシュ関数を計算したいと考えています。次のように私はこのクラスを使用BodyChannel chan []byte
バイトゴランのチャンネル使用率
:
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
が定義されている: は私がio.Writerを実装して自分のクラスを渡すio.TeeReader(request.Body, &writerToHash)
を使って身体を読んでこれを行うには
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を使用してそれを見ます。この場合、everythongは正常に動作します。 問題は、メッセージが書き込み機能の複数の部分に分割されている場合です。この場合、私はPRINT1で参照してください。
[最初のバイト]:
[次〜450バイト]:B、C、D、...
[最後の〜550バイト]:ワット[最後の部分が始まる〜450のバイトが、出発]
:
[最初のバイト]、X、Yは、...
しかし
はPRINT 2に私は別の画像を参照して、W、X 、y ...:w、x、y、...
私は実際に最後の過去を2回取得しますが、同じサイズではありません。
私はこれがなぜ起こっているのか分かりませんし、何か助けに感謝します。 io.Writer
documentationから
ジムに感謝します。ところで、あなたはストリームが常に最初のバイト+残りに分割された理由を知っているかもしれませんか? – Ety
@Ety:TeeReaderは読者から読まれたものを正確に書いています。したがって、1バイトが 'request.Body'から読み込まれた場合、1バイトは' writerToHash'に書き込まれます。小さな読み書き操作が問題になる場合(あなたの場合は問題ありません)、bufioを使用してより大きな操作にバッチ処理を行います。 – JimB