账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    go iris 如何用 pipe 文件
    57
    0

    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 的做法来做的)

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • ╰°放开那萌比o- 普通会员 1楼

      在Go语言中,你可以使用pipe函数来读取文件中的数据。pipe函数将两个管道连接起来,然后在两个管道的输出之间创建一个输出流。

      以下是一个例子,展示了如何使用pipe函数读取iris文件中的数据:

      ```go package main

      import ( "bufio" "fmt" "os" "strconv" "strings" )

      func main() { // 创建两个管道 p1, p2 := os.pipe()

      // 创建一个文件描述符
      f, err := os.Create("iris.txt")
      if err != nil {
          fmt.Println(err)
          return
      }
      defer f.Close()
      
      // 创建一个读取器
      // 使用管道读取数据
      go func() {
          // 使用管道读取数据
          fmt.Print("Enter a number: ")
          num, err := strconv.Atoi(strings.TrimSpace(string(p1)))
          if err != nil {
              fmt.Println(err)
              return
          }
          // 在数据中添加输入数字
          fmt.Print("Enter another number: ")
          num2, err := strconv.Atoi(strings.TrimSpace(string(p2)))
          if err != nil {
              fmt.Println(err)
              return
          }
          // 将读取器的数据写入文件
          fmt.Print("Enter a number to remove: ")
          n, err := strconv.Atoi(strings.TrimSpace(string(p1)))
          if err != nil {
              fmt.Println(err)
              return
          }
          n--
          _, err = f.WriteString(strconv.Itoa(n))
          if err != nil {
              fmt.Println(err)
              return
          }
          fmt.Println("Numbers removed:", n)
      }()
      
      // 关闭管道
      p1.Close()
      p2.Close()
      

      } ```

      在这个例子中,我们首先创建了两个管道p1p2。然后,我们创建了一个文件描述符f,并使用os.Create函数创建了一个读取器。接着,我们定义了一个go函数,这个函数将读取器读取的数据写入文件,并在文件中添加输入数字。

      go函数中,我们首先提示用户输入一个数字。然后,我们提示用户输入另一个数字,并将这两个数字分别写入文件。

      最后,我们关闭了管道p1p2

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部