Функция ReadAtLeast
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
ReadAtLeast читает из r в buf, пока не прочитает хотя бы min байтов. Он возвращает количество скопированных байтов и ошибку, если было прочитано меньше байтов. Ошибка EOF, только если не было прочитано ни одного байта. Если EOF происходит после считывания менее чем min байтов, ReadAtLeast возвращает ErrUnexpectedEOF. Если min больше, чем длина буфера, ReadAtLeast возвращает ErrShortBuffer. По возвращении n >= min, только если err == nil. Если r возвращает ошибку, прочитав хотя бы min байтов, ошибка сбрасывается.
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 14)
if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
// буфер меньше минимального размера чтения.
shortBuf := make([]byte, 3)
if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
fmt.Println("error:", err)
}
// минимальный размер чтения больше, чем поток io.Reader
longBuf := make([]byte, 64)
if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
fmt.Println("error:", err)
}
}
Вывод:
some io.Reader
error: short buffer
error: unexpected EOF
Функция ReadFull
func ReadFull(r Reader, buf []byte) (n int, err error)
ReadFull читает точно len(buf) байтов из r в buf. Он возвращает количество скопированных байтов и ошибку, если было прочитано меньше байтов. Ошибка EOF, только если не было прочитано ни одного байта. Если EOF происходит после чтения некоторых, но не всех байтов, ReadFull возвращает ErrUnexpectedEOF. По возвращении n == len(buf) только тогда, когда err == nil. Если r возвращает ошибку, прочитав по крайней мере len(buf) байтов, ошибка сбрасывается.
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 4)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
// минимальный размер чтения больше, чем поток io.Reader
longBuf := make([]byte, 64)
if _, err := io.ReadFull(r, longBuf); err != nil {
fmt.Println("error:", err)
}
}
Вывод:
some
error: unexpected EOF
Тип Reader
Reader - это интерфейс, который оборачивает базовый метод Read.
type Reader interface {
Read(p []byte) (n int, err error)
}
Read читает до len(p) байтов в p. Он возвращает количество прочитанных байтов (0 <= n <= len(p)) и обнаруженную ошибку. Даже если Read возвращает n < len(p), он может использовать все p как пустое место во время вызова. Если некоторые данные доступны, но не len(p) байтов, Read обычно возвращает то, что доступно, вместо ожидания большего.
Когда Read успешно обнаруживает ошибку или условие конца файла после успешного чтения n > 0 байтов, он возвращает количество прочитанных байтов. Он может вернуть (не nil) ошибку из того же вызова или вернуть ошибку (и n == 0) из последующего вызова. Примером этого общего случая является то, что Reader, возвращающий ненулевое число байтов в конце входного потока, может вернуть либо err == EOF, либо err == nil. Следующее чтение должно вернуть 0, EOF.
Вызывающие всегда должны обрабатывать n > 0 байтов, возвращенных до рассмотрения ошибки err. Это правильно обрабатывает ошибки ввода-вывода, возникающие после чтения некоторых байтов, а также обоих разрешенных вариантов поведения EOF.
Реализации Read не рекомендуется возвращать счетчик нулевых байтов с ошибкой nil, кроме случаев, когда len(p) == 0. Вызывающие операторы должны обрабатывать возврат 0 и nil как указание того, что ничего не произошло; в частности это не указывает на EOF.
Реализации не должны сохранять p (входной срез байтов).
Функция LimitReader
func LimitReader(r Reader, n int64) Reader
LimitReader возвращает Reader, который читает из r, но останавливается с EOF после n байтов. Базовой реализацией является *LimitedReader.
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
lr := io.LimitReader(r, 4)
if _, err := io.Copy(os.Stdout, lr); err != nil {
log.Fatal(err)
}
}
Вывод:
some
Функция MultiReader
func MultiReader(readers ...Reader) Reader
MultiReader возвращает Reader, который является логическим объединением предоставленных входных считывателей. Они читаются последовательно. Как только все входы вернут EOF, Read вернет EOF. Если кто-либо из читателей вернет ошибку, отличную от nil, не EOF, Read вернет эту ошибку.
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
r1 := strings.NewReader("first reader ")
r2 := strings.NewReader("second reader ")
r3 := strings.NewReader("third reader\n")
r := io.MultiReader(r1, r2, r3)
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
}
Вывод:
first reader second reader third reader
Функция TeeReader
func TeeReader(r Reader, w Writer) Reader
TeeReader возвращает Reader, который пишет в w то, что он читает из r. Все чтения из r, выполненные через него, сопоставляются с соответствующими записями в w. Внутренняя буферизация отсутствует - запись должна завершиться до завершения чтения. Любая ошибка, обнаруженная во время записи, сообщается как ошибка чтения.
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
var buf bytes.Buffer
tee := io.TeeReader(r, &buf)
printall := func(r io.Reader) {
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
}
printall(tee)
printall(&buf)
}
Вывод:
some io.Reader stream to be read
some io.Reader stream to be read
Читайте также:
Комментариев нет:
Отправить комментарий