Ce face io.NewSectionReader
io.NewSectionReader primește o sursă care permite citirea de la orice poziție (io.ReaderAt: *os.File, *bytes.Reader, *strings.Reader) și returnează un *io.SectionReader limitat la octeții [off, off+n). Pentru el, poziția 0 este off, iar după n octeți vine io.EOF.
SectionReader implementează Read, Seek, ReadAt și Size. Pentru că folosește ReadAt, nu mută poziția sursei, deci poți avea mai multe secțiuni din același fișier citite în paralel. Este folosit la formate cu porțiuni la poziții cunoscute (arhive, imagini) și la descărcarea pe bucăți.
Parametri
| Parametru | Descriere |
|---|---|
r |
Sursa cu acces direct (io.ReaderAt). |
off |
Poziția de început a secțiunii. |
n |
Lungimea secțiunii, în octeți. |
Ce returnează
Un *io.SectionReader.
Exemple
Exemplul 1: O porțiune dintr-un text
package main
import (
"fmt"
"io"
"strings"
)
func main() {
sursa := strings.NewReader("COD:RO123 NUME:Ana Popescu ORAS:Iasi")
nume := io.NewSectionReader(sursa, 15, 11)
date, _ := io.ReadAll(nume)
fmt.Printf("%q, dimensiune secțiune: %d\n", date, nume.Size())
oras := io.NewSectionReader(sursa, 32, 100) // cere mai mult decât există
date, _ = io.ReadAll(oras)
fmt.Printf("%q\n", date)
}
Rezultat
"Ana Popescu", dimensiune secțiune: 11
"Iasi"
Exemplul 2: Un fișier împărțit în bucăți citite în paralel
package main
import (
"fmt"
"io"
"os"
"sync"
)
func main() {
os.WriteFile("date.bin", []byte("AAAABBBBCCCCDD"), 0o644)
f, _ := os.Open("date.bin")
defer f.Close()
info, _ := f.Stat()
const bucata = 4
var wg sync.WaitGroup
parti := make([]string, (info.Size()+bucata-1)/bucata)
for i := range parti {
wg.Go(func() {
s := io.NewSectionReader(f, int64(i)*bucata, bucata)
date, _ := io.ReadAll(s)
parti[i] = string(date)
})
}
wg.Wait()
fmt.Println(parti)
}
Rezultat
[AAAA BBBB CCCC DD]
Greșeli frecvente
- Încerci să folosești un
io.Readerobișnuit (de exemplu corpul unei cereri HTTP).SectionReaderare nevoie deReadAt, adică de acces la orice poziție.
Comenzi înrudite
io.LimitReader: Învelește un Reader astfel încât să poată fi citiți din el cel mult n octeți; după aceea dă io.EOF.os.File.Seek: Mută poziția curentă de citire/scriere din fișier, față de început, de poziția curentă sau de final.io.NewOffsetWriter: Creează un Writer care scrie într-o destinație cu acces direct (ca un fișier) începând de la poziția off.io.Reader: Interfața pentru orice sursă de date din care se poate citi: fișiere, text, conexiuni, răspunsuri HTTP.