为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 写入 http 响应会中断输入读取吗?

Golang 写入 http 响应会中断输入读取吗?

Go
拉风的咖菲猫 2021-09-13 15:30:56
我正在尝试在 Go 中编写一个小型 web 应用程序,用户可以在其中以多部分形式上传 gzipped 文件。应用程序解压缩并解析文件并将一些输出写入响应。但是,当我开始写入响应时,我不断遇到输入流看起来已损坏的错误。不写入响应可以解决问题,就像从非 gzipped 输入流读取一样。这是一个示例 http 处理程序:func(w http.ResponseWriter, req *http.Request) {//Get an input stream from the multipart reader//and read it using a scannermultiReader, _ := req.MultipartReader()part, _ := multiReader.NextPart()gzipReader, _ := gzip.NewReader(part)scanner := bufio.NewScanner(gzipReader)//Strings read from the input stream go to this channel     inputChan := make(chan string, 1000)//Signal completion on this channel donechan := make(chan bool, 1)//This goroutine just reads text from the input scanner//and sends it into the channel go func() {    for scanner.Scan() {        inputChan <- scanner.Text()    }           close(inputChan)}()//Read lines from input channel. They all either start with #//or have ten tab-separated columnsgo func() {    for line := range inputChan {        toks := strings.Split(line, "\t")        if len(toks) != 10 && line[0] != '#' {            panic("Dang.")        }    }    donechan <- true }()//periodically write some random text to the responsego func() {    for {        time.Sleep(10*time.Millisecond)             w.Write([]byte("write\n some \n output\n"))    }}()//wait until we're done to return<-donechan}奇怪的是,这段代码每次都会发生恐慌,因为它总是遇到少于 10 个标记的行,尽管每次都在不同的位置。注释掉写入响应的行可以解决问题,就像从非 gzip 输入流中读取一样。我错过了一些明显的东西吗?如果从 gzip 文件而不是纯文本格式的文件中读取,为什么写入响应会中断?为什么它会破裂?
查看完整描述

1 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

HTTP 协议不是全双工的:它是基于请求-响应的。您应该只在完成读取输入后发送输出。


在您的代码中,您在频道上使用forwith range。这将尝试读取通道直到它关闭,但你永远不会关闭inputChan.


如果您从不 close inputChan,则永远不会到达以下行:


donechan <- true 

因此从donechan块接收:


<-donechan

您必须在inputChan达到 EOF 时关闭:


go func() {

    for scanner.Scan() {

        inputChan <- scanner.Text()

    }       

    close(inputChan) // THIS IS NEEDED

}()


查看完整回答
反对 回复 2021-09-13
  • 1 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信