En Python, par exemple, je peux faire ce qui suit:
realout = sys.stdout
sys.stdout = StringIO.StringIO()
some_function() # prints to stdout get captured in the StringIO object
result = sys.stdout.getvalue()
sys.stdout = realout
Pouvez-vous faire cela dans Go?
J'accepte que vous utilisiez le fmt.Fprint
fonctionne si vous pouvez le gérer. Cependant, si vous ne contrôlez pas le code dont vous capturez la sortie, vous n'aurez peut-être pas cette option.
La réponse de Mostafa fonctionne, mais si vous voulez le faire sans fichier temporaire, vous pouvez utiliser os.Pipe . Voici un exemple équivalent à celui de Mostafa avec du code inspiré du package de test de Go.
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func print() {
fmt.Println("output")
}
func main() {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
print()
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
fmt.Println("previous output:")
fmt.Print(out)
}
Cette réponse est similaire aux précédentes mais semble plus propre en utilisant io/ioutil.
http://play.golang.org/p/fXpK0ZhXXf
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
fmt.Println("Hello, playground") // this gets captured
w.Close()
out, _ := ioutil.ReadAll(r)
os.Stdout = rescueStdout
fmt.Printf("Captured: %s", out) // prints: Captured: Hello, playground
}
Je ne le recommande pas, mais vous pouvez y parvenir en modifiant os.Stdout
. Puisque cette variable est de type os.File
, votre sortie temporaire devrait également être un fichier.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
func print() {
fmt.Println("output")
}
func main() {
// setting stdout to a file
fname := filepath.Join(os.TempDir(), "stdout")
fmt.Println("stdout is now set to", fname)
old := os.Stdout // keep backup of the real stdout
temp, _ := os.Create(fname) // create temp file
os.Stdout = temp
print()
// back to normal state
temp.Close()
os.Stdout = old // restoring the real stdout
// reading our temp stdout
fmt.Println("previous output:")
out, _ := ioutil.ReadFile(fname)
fmt.Print(string(out))
}
Je ne le recommande pas car c'est trop de piratage, et pas très idiomatique dans Go. Je suggère de passer un io.Writer
aux fonctions et à l'écriture des sorties. C'est la meilleure façon de faire presque la même chose.
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func print(w io.Writer) {
fmt.Fprintln(w, "output")
}
func main() {
fmt.Println("print with byes.Buffer:")
var b bytes.Buffer
print(&b)
fmt.Print(b.String())
fmt.Println("print with os.Stdout:")
print(os.Stdout)
}
Je pense que l'idée n'est pas du tout recommandée (condition de concurrence), mais je suppose que l'on peut jouer avec os.Stdout d'une manière similaire/analogique à votre exemple.