Golang ReadWriteCloser 作为 io.File

问题描述 投票:0回答:1

在具有

io.ReadWriteCloser
实例的 golang 中,如何获取其表示(代理类型)作为
*os.File
实例(例如为
exec.Cmd.ExtraFiles
提供)

首先想到的是使用

os.Pipe
方法。但这样的存根仍然是单向的(只读或只写)。

那么如何将

io.ReadWriteCloser
完全表示为
*os.File
例如

func something(stream io.ReadWriteCloser) {
  cmd := exec.Command("comm")

  var wrapped *os.File = wrappAsFile(stream) // How this could be achieved?

  cmd.ExtraFiles := []*File{wrapped}
}

我可以看到的简化解决方案如下所示。尽管如此(正如我之前提到的)它只涵盖了 Reader 流程。

func something(stream io.ReadWriteCloser) {
  cmd := exec.Command("comm")

  r, w, _ := os.Pipe()

  go func() {
     io.Copy(w, stream)
     w.Close()
  }()

  cmd.ExtraFiles := []*File{r}
}

谢谢

go read-write
1个回答
0
投票

如果您只能使用 POSIX 系统,则可以使用

socketpair
创建全双工管道。您可以通过
golang.org/x/sys/unix
包作为
syscall.Socketpair

访问此内容
func socketpair() (*os.File, *os.File, error) {
    fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
    if err != nil {
        return nil, nil, err
    }

    if err := syscall.SetNonblock(int(fds[0]), true); err != nil {
        return nil, nil, err
    }
    if err := syscall.SetNonblock(int(fds[1]), true); err != nil {
        return nil, nil, err
    }

    f0 := os.NewFile(uintptr(fds[0]), "socket-0")
    f1 := os.NewFile(uintptr(fds[1]), "socket-1")

    return f0, f1, nil
}

然后您可以通过几个

io.ReadWriteCloser
调用连接到
io.Copy

    // We'll use f0 as the local side of the pipe, and pass along f1 to the child process
    f0, f1, err := socketpair()
    if err != nil {
        log.Fatal(err)
    }

    go func() {
        io.Copy(f0, rw)
        f0.Close()
    }()

    go func() {
        io.Copy(rw, f0)
    }()
© www.soinside.com 2019 - 2024. All rights reserved.