go iris 如何用 pipe 文件

新手上路,请多包涵

Nodejs 中有 pipe 可以直接转发 request 的数据导 response 中,最近在学习 GO 和 Iris,想用 GO 也做同样的功能碰到一些问题

在编写代码的过程中,碰到好些问题,都在下面代码注释中

func pipeImage(ctx iris.Context) {
    filePath := ctx.FormValue("url")
    r, w := io.Pipe()
    go func() {
        defer func() {
            fmt.Println("w.close")
            w.Close()
        }()
    
        client := &http.Client{}
        resp, err := client.Get(url)
        if err != nil {
            fmt.Println(err)
            panic(err)
        }
        defer resp.Body.Close()
        fmt.Println("io.Copy")
        // 运行到 copy 就返回了,会继续运行下面的 r.Read(data), 没有打印出下面的 io.Copy end, 请问这是为什么?
        io.Copy(w, resp.Body)
        fmt.Println("io.Copy end")
    }
    // 这里又申明了一个 byte,很无奈,不知道有什么方法可以方便的将 pipe 中 Reader 的数据发下去
    var data []byte
    fmt.Println("r.read")
    // 运行到这里进入上面 go 的进程
    r.Read(data)
    // 这边看了一下打印出来的值, length 是0,没有写入成功还是写入成异步了,开始写就直接读了?
    // 这边我感觉有点问题,如果不设置缓存的话,是否大文件的转发会分成很多批次写入读取,但是这边只能读取一次,不知道有什么方法可以监控进度状态
    fmt.Println("r.read end", len(data))
    // 输出0字节
    ctx.Binary(data)
}

请问上面都是为什么造成的,感觉有点绕,特别不能理解的是 pipe 的读取和状态控制。
还有 Iris 返回的话如果又申请了一个 byte 感觉还是有问题,没把 pipe 的特点发挥出来。
是否这个功能不适合用 pipe?(我是参考 Nodejs 的做法来做的)

阅读 3.1k
1 个回答
  1. 你的data只声明了,是nil slice啊,当然是0
  2. 外面的goroutine退出了,里面的就不会执行fmt.Println("io.Copy end"),外面sleep或者用sync.waitgroup吧
time.Sleep(time.Duration(2) * time.Second)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题