如何将os.Stdout输出复制到字符串变量

时间:2018-07-05 04:37:23

标签: go output

我有这样的功能:

package main

import (
    "fmt"
)

// PrintSomething prints some thing
func PrintSomething() {
    fmt.Println("print something")
}

func main() {
    PrintSomething()
}

如何将PrintSomething包装到另一个调用CaptureSomething的函数中,以将字符串“ print something”保存到变量并返回它?

3 个答案:

答案 0 :(得分:5)

创建pipe并将stdout设置为管道编写器。启动goroutine将管道读取器复制到缓冲区。完成后,关闭管道编写器并等待goroutine完成读取。以字符串形式返回缓冲区。

new Vue({
  el: '#app'  
})

}

像这样使用它:

// capture replaces os.Stdout with a writer that buffers any data written 
// to os.Stdout. Call the returned function to cleanup and get the data
// as a string.
func capture() func() (string, error) {
    r, w, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    done := make(chan error, 1)

    save := os.Stdout
    os.Stdout = w

    var buf strings.Builder

    go func() {
        _, err := io.Copy(&buf, r)
        r.Close()
        done <- err
    }()

    return func() (string, error) {
        os.Stdout = save
        w.Close()
        err := <-done
        return buf.String(), err
    }

playground example

答案 1 :(得分:0)

使用其中之一,以适合您的方式

package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
    "strings"
)

func PrintSomething() {
    fmt.Println("print something")
}

func PrintSomethingBig() {
    for i := 0; i < 100000; i++ {
        fmt.Println("print something")
    }
}

func PrintSomethingOut(out io.Writer) {
    fmt.Fprintln(out, "print something to io.Writer")
}

func PrintSomethingString() string {
    return fmt.Sprintln("print something into a string")
}

// not thread safe
// modified by zlynx@acm.org from original at http://craigwickesser.com/2015/01/capture-stdout-in-go/
func captureStdout(f func()) string {
    old := os.Stdout
    r, w, _ := os.Pipe()
    os.Stdout = w

    go func() {
        f()
        w.Close()
    }()

    buf := &bytes.Buffer{}
    // Will complete when the goroutine calls w.Close()
    io.Copy(buf, r)

    // Clean up.
    os.Stdout = old
    r.Close()

    return buf.String()
}

func main() {
    str1 := &strings.Builder{}
    str2 := PrintSomethingString()
    PrintSomethingOut(str1)
    PrintSomethingOut(os.Stdout)
    str3 := captureStdout(PrintSomething)
    str4 := captureStdout(PrintSomethingBig)
    fmt.Println("string 1 is", str1)
    fmt.Println("string 2 is", str2)
    fmt.Println("string 3 is", str3)
    fmt.Println("string 4 len", len(str4))
}

答案 2 :(得分:0)

例如,

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

// PrintSomething prints some thing
func PrintSomething() {
    fmt.Println("print something")
}

func CaptureSomething() (string, error) {
    defer func(stdout *os.File) {
        os.Stdout = stdout
    }(os.Stdout)
    out, err := ioutil.TempFile("", "stdout")
    if err != nil {
        return "", err
    }
    defer out.Close()
    outname := out.Name()
    os.Stdout = out

    PrintSomething()

    err = out.Close()
    if err != nil {
        return "", err
    }
    data, err := ioutil.ReadFile(outname)
    if err != nil {
        return "", err
    }
    os.Remove(outname)
    return string(data), nil
}

func main() {
    s, err := CaptureSomething()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Print(s)
    }
}

游乐场:https://play.golang.org/p/O2kSegxYeGy

输出:

print something