io.MultiWriter în Go

Creează un Writer care trimite fiecare scriere la toți Writer-ii dați, ca tee din Unix.

Sintaxă
func MultiWriter(writers ...Writer) Writer

Ce face io.MultiWriter

Fiecare Write pe rezultatul lui io.MultiWriter este repetat, în ordine, pe fiecare Writer dat. Dacă unul dă eroare, scrierea se oprește și eroarea este returnată (cei de după nu mai primesc datele).

Folosiri tipice: jurnal pe ecran și în fișier deodată, salvarea unui fișier descărcat și calculul hash-ului lui într-o singură trecere, copii de siguranță.

Parametri

Parametru Descriere
writers Destinațiile.

Ce returnează

Un io.Writer.

Exemple

Exemplul 1: Pe ecran și în fișier

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    f, _ := os.Create("bon.txt")
    defer f.Close()

    w := io.MultiWriter(os.Stdout, f)
    fmt.Fprintln(w, "Bon fiscal nr. 315")
    fmt.Fprintln(w, "Cafea      32,50 lei")

    date, _ := os.ReadFile("bon.txt")
    fmt.Printf("în fișier: %d octeți\n", len(date))
}

Rezultat

Bon fiscal nr. 315
Cafea      32,50 lei
în fișier: 40 octeți

Exemplul 2: Copiere și hash într-o singură trecere

package main

import (
    "crypto/sha256"
    "fmt"
    "io"
    "os"
    "strings"
)

func main() {
    descarcare := strings.NewReader("conținutul arhivei descărcate")
    f, _ := os.Create("arhiva.zip")
    defer f.Close()
    h := sha256.New()

    n, err := io.Copy(io.MultiWriter(f, h), descarcare)
    fmt.Println("octeți:", n, "eroare:", err)
    fmt.Printf("sha256: %x\n", h.Sum(nil))
}

Rezultat

octeți: 31 eroare: <nil>
sha256: ddb2be25addbc79eef17c9464ccbacacb7f7270a334ec172096d3c5e3245d9b0

Greșeli frecvente

  • Pui un Writer lent (rețea) împreună cu unul rapid. Fiecare scriere așteaptă după cel mai lent; dacă unul dă eroare, ceilalți rămân cu date incomplete.

Comenzi înrudite

  • io.MultiReader: Leagă mai multe Reader-e unul după altul, ca și cum ar fi o singură sursă continuă.
  • io.TeeReader: Returnează un Reader care, pe măsură ce citești din r, scrie aceiași octeți și în w.
  • io.Writer: Interfața pentru orice destinație în care se pot scrie octeți: fișiere, ecran, buffer-e, răspunsuri HTTP.
  • log.SetOutput: Schimbă locul în care scrie jurnalul implicit: alt fișier, ieșirea standard, un buffer sau mai multe deodată.