Ce face io.CopyN
io.CopyN copiază primii n octeți din src. Dacă sursa are mai puțini, copiază ce există și returnează io.EOF, ca să știi că lipsesc date.
Este utilă pentru formate cu lungime cunoscută: un antet de n octeți, o porțiune dintr-un fișier, primele n octeți dintr-o încărcare. Pentru a limita cât citești dintr-o sursă nesigură poți folosi și io.LimitReader.
Parametri
| Parametru | Descriere |
|---|---|
dst |
Destinația. |
src |
Sursa. |
n |
Numărul de octeți de copiat. |
Ce returnează
Octeții copiați și nil dacă au fost exact n; altfel o eroare (io.EOF dacă sursa s-a terminat mai devreme).
Exemple
Exemplul 1: Primii octeți dintr-un text
package main
import (
"fmt"
"io"
"os"
"strings"
)
func main() {
src := strings.NewReader("Universitatea din Iași")
n, err := io.CopyN(os.Stdout, src, 13)
fmt.Println()
fmt.Println("copiați:", n, "eroare:", err)
rest, _ := io.ReadAll(src)
fmt.Printf("au rămas: %q\n", rest)
}
Rezultat
Universitatea
copiați: 13 eroare: <nil>
au rămas: " din Iași"
Exemplul 2: Sursa prea scurtă
package main
import (
"fmt"
"io"
"strings"
)
func main() {
var sb strings.Builder
n, err := io.CopyN(&sb, strings.NewReader("abc"), 10)
fmt.Printf("copiați: %d, text: %q, eroare: %v\n", n, sb.String(), err)
}
Rezultat
copiați: 3, text: "abc", eroare: EOF
Exemplul 3: Împărțirea unui fișier în bucăți
package main
import (
"errors"
"fmt"
"io"
"os"
)
func main() {
os.WriteFile("mare.txt", []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0o644)
in, _ := os.Open("mare.txt")
defer in.Close()
for parte := 1; ; parte++ {
nume := fmt.Sprintf("parte%d.txt", parte)
out, _ := os.Create(nume)
n, err := io.CopyN(out, in, 16)
out.Close()
if n > 0 {
date, _ := os.ReadFile(nume)
fmt.Printf("%s: %s\n", nume, date)
} else {
os.Remove(nume)
}
if errors.Is(err, io.EOF) {
break
}
}
}
Rezultat
parte1.txt: 0123456789ABCDEF
parte2.txt: GHIJKLMNOPQRSTUV
parte3.txt: WXYZ
Greșeli frecvente
- Ignori
io.EOFde laCopyN. Aici înseamnă că sursa a avut mai puțin denocteți, ceea ce poate fi o eroare de format.
Comenzi înrudite
io.Copy: Copiază toate datele dintr-un Reader într-un Writer, pe bucăți, fără să le țină pe toate în memorie.io.ReadFull: ReadFull umple complet buffer-ul din Reader; ReadAtLeast citește cel puțin min octeți.io.Reader: Interfața pentru orice sursă de date din care se poate citi: fișiere, text, conexiuni, răspunsuri HTTP.