Ce face os.Pipe
os.Pipe returnează două fișiere legate: w pentru scriere și r pentru citire. Datele scrise în w apar, în aceeași ordine, la r. Citirea așteaptă până vin date sau până se închide w (atunci primește io.EOF).
Spre deosebire de io.Pipe, care există doar în memoria programului, os.Pipe este un pipe real al sistemului. Îl poți da unui proces copil ca intrare sau ieșire (cmd.Stdin, cmd.Stdout) sau îl poți folosi ca să capturezi ce scrie programul tău pe os.Stdout.
Ce returnează
Capătul de citire, capătul de scriere și nil, sau o eroare. Închide ambele capete când nu mai ai nevoie de ele.
Exemple
Exemplul 1: Scriere într-o goroutine, citire în main
w.Close() semnalează sfârșitul datelor; fără el, io.ReadAll ar aștepta la nesfârșit.
package main
import (
"fmt"
"io"
"os"
)
func main() {
r, w, err := os.Pipe()
if err != nil {
fmt.Println("eroare:", err)
return
}
go func() {
defer w.Close()
for _, oras := range []string{"Iași", "Cluj", "Timișoara"} {
fmt.Fprintln(w, oras)
}
}()
date, _ := io.ReadAll(r)
r.Close()
fmt.Print(string(date))
}
Rezultat
Iași
Cluj
Timișoara
Exemplul 2: Capturarea a ce scrie fmt.Println
Înlocuim temporar os.Stdout cu capătul de scriere, apoi citim ce s-a scris.
package main
import (
"fmt"
"io"
"os"
"strings"
)
func salut(nume string) {
fmt.Println("Bună ziua,", nume)
}
func main() {
original := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
salut("Ana")
w.Close()
os.Stdout = original
capturat, _ := io.ReadAll(r)
fmt.Printf("funcția a scris: %q\n", strings.TrimSpace(string(capturat)))
}
Rezultat
funcția a scris: "Bună ziua, Ana"
Greșeli frecvente
- Uiți să închizi capătul de scriere. Cititorul nu primește niciodată
io.EOFși programul se blochează. - Scrii mult în pipe în aceeași goroutine care citește mai târziu. Pipe-ul are un buffer mic (de obicei 64 KB); când se umple, scrierea se blochează. Scrie și citește în goroutine diferite.
Comenzi înrudite
io.Pipe: Creează un pipe în memorie: ce scrie o goroutine la capătul Writer citește alta la capătul Reader.os.IsTimeout: Spune dacă o eroare înseamnă că a expirat timpul de așteptare (timeout) al unei operații.exec.Cmd.StdoutPipe: Returnează un Reader legat de ieșirea comenzii, ca să citești rezultatul pe măsură ce apare.io.ReadAll: Citește tot ce oferă un Reader, până la final, și returnează datele ca slice de octeți.