Интерфейс io.Reader представляет сущность, из которой вы можете прочитать поток байтов.
type Reader interface {
Read(buf []byte) (n int, err error)
}
Read читает до len(buf) байтов в buf и возвращает количество прочитанных байтов - он возвращает ошибку io.EOF, когда заканчивается поток.
Стандартная библиотека предоставляет множество реализаций Reader (включая байтовые буферы в памяти, файлы и сетевые подключения), и Readers принимаются в качестве входных данных многими утилитами (включая реализации HTTP клиента и сервера).
Используйте встроенный ридер
Например, вы можете создать Reader из строки, используя функцию strings.Reader, а затем передать Reader непосредственно в функцию http.Post в пакете net/http. Затем Reader используется в качестве источника данных для POST запроса.
r := strings.NewReader("my request")
resp, err := http.Post("http://foo.bar",
"application/x-www-form-urlencoded", r)
Поскольку http.Post использует Reader вместо []byte, тривиально, например, использовать вместо него содержимое файла.
Читайте прямо из потока байтов
Вы можете использовать функцию Read напрямую (это наименее распространенный вариант использования).
r := strings.NewReader("abcde")
buf := make([]byte, 4)
for {
n, err := r.Read(buf)
fmt.Println(n, err, buf[:n])
if err == io.EOF {
break
}
}
4 <nil> [97 98 99 100]
1 <nil> [101]
0 EOF []
Используйте io.ReadFull для считывания ровно len(buf) байтов в buf:
r := strings.NewReader("abcde")
buf := make([]byte, 4)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Println(buf)
if _, err := io.ReadFull(r, buf); err != nil {
fmt.Println(err)
}
[97 98 99 100]
unexpected EOF
Используйте ioutil.ReadAll, чтобы прочитать все:
r := strings.NewReader("abcde")
buf, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Println(buf)
[97 98 99 100 101]
Буферизированное чтение и сканирование
Типы bufio.Reader и bufio.Scanner обертывают Reader, создавая другой Reader, который также реализует интерфейс, но обеспечивает буферизацию и некоторую помощь для ввода текста.
В этом примере мы используем bufio.Scanner для подсчета количества слов в тексте.
const input = `Beware of bugs in the above code;
I have only proved it correct, not tried it.`
scanner := bufio.NewScanner(strings.NewReader(input))
// Настройка функции разделения.
scanner.Split(bufio.ScanWords)
count := 0
for scanner.Scan() {
count++
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
fmt.Println(count)
16
Читайте также:
- Основы Go: интерфейс Reader
- Читать файл (stdin) построчно в Golang
- Эффективный Go: вложение (embedding)
Комментариев нет:
Отправить комментарий