Тип io.SectionReader
Тип io.SectionReader используется для создания объекта чтения,
который представляет собой срез (фрагмент) данных из другого
источника данных, реализующего интерфейс io.ReaderAt.
В первый параметр мы передаем объект, поддерживающий чтение
по смещению (например, файл или массив байт), во второй -
начальное смещение (offset) от начала данных, а в третий -
количество байт, которые будут доступны для чтения.
Синтаксис
io.NewSectionReader(readerAt, offset, length)
Пример
Давайте создадим участок чтения из строки байт (слайса байт), начиная со смещения 5 и длиной 10 байт:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
// Создаем источник данных в виде строки
data := "01234567890123456789"
reader := strings.NewReader(data)
// Создаем SectionReader для чтения байтов с 5-го по 14-й
sectionReader := io.NewSectionReader(reader, 5, 10)
// Читаем фрагмент в срез байт
buf := make([]byte, 10)
n, err := sectionReader.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("%s", string(buf[:n]))
}
Результат выполнения кода:
"5678901234"
Пример
Продемонстрируем использование метода Seek для изменения
текущей позиции чтения внутри SectionReader:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
// Исходные данные
data := "0123456789abcdef"
reader := strings.NewReader(data)
// Создаем SectionReader для фрагмента с 0 по 16 байт
sectionReader := io.NewSectionReader(reader, 0, 16)
// Перемещаем указатель на 5 байт от начала
sectionReader.Seek(5, io.SeekStart)
// Читаем 5 байт
buf := make([]byte, 5)
n, err := sectionReader.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("%s", string(buf[:n]))
}
Результат выполнения кода:
"56789"
Пример
Покажем, как работает метод Size, возвращающий размер
фрагмента, а также чтение с конца фрагмента с использованием
отрицательного смещения:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
// Исходные данные длиной 20 байт
data := "0123456789abcdefghij"
reader := strings.NewReader(data)
// Создаем SectionReader для фрагмента с 5 по 20 байт
sectionReader := io.NewSectionReader(reader, 5, 15)
// Получаем размер фрагмента
size := sectionReader.Size()
fmt.Printf("size: %d\n", size)
// Перемещаем указатель на 10 байт назад от конца
sectionReader.Seek(-10, io.SeekEnd)
// Читаем 5 байт
buf := make([]byte, 5)
n, err := sectionReader.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("tail: %s", string(buf[:n]))
}
Результат выполнения кода:
"size: 15"
"tail: 45678"
Смотрите также
-
тип
io.ReaderAt,
который является основой для создания SectionReader -
функцию
io.LimitReader,
которая ограничивает количество байт для чтения -
метод
os.File.Seek,
который позволяет устанавливать позицию в файле -
функцию
io.ReadFull,
которая гарантированно читает указанное количество байт