Функция io.TeeReader
Функция io.TeeReader возвращает новый io.Reader,
который читает данные из переданного ей ридера и одновременно
записывает все прочитанные данные в указанный врайтер.
В первый параметр мы передаем исходный ридер для чтения данных,
во второй параметр мы передаем врайтер, в который будут
дублироваться прочитанные данные.
Синтаксис
io.TeeReader(reader io.Reader, writer io.Writer) io.Reader
Пример использования с файлами
Давайте прочитаем данные из файла и одновременно запишем их
в другой файл с помощью io.TeeReader:
package main
import (
"io"
"os"
)
func main() {
srcFile, err := os.Open("source.txt")
if err != nil {
panic(err)
}
defer srcFile.Close()
dstFile, err := os.Create("destination.txt")
if err != nil {
panic(err)
}
defer dstFile.Close()
teeReader := io.TeeReader(srcFile, dstFile)
data, err := io.ReadAll(teeReader)
if err != nil {
panic(err)
}
os.Stdout.Write(data)
}
В этом примере данные из source.txt одновременно читаются
и записываются в destination.txt, а также выводятся
в стандартный вывод.
Пример с подсчетом байт
Давайте используем io.TeeReader для подсчета количества
прочитанных байт:
package main
import (
"bytes"
"fmt"
"io"
)
type Counter struct {
count int64
}
func (c *Counter) Write(p []byte) (int, error) {
c.count += int64(len(p))
return len(p), nil
}
func main() {
data := []byte("hello world")
reader := bytes.NewReader(data)
counter := &Counter{}
teeReader := io.TeeReader(reader, counter)
res, err := io.ReadAll(teeReader)
if err != nil {
panic(err)
}
fmt.Printf("Прочитано данных: %s\n", string(res))
fmt.Printf("Количество байт: %d\n", counter.count)
}
Результат выполнения кода:
"Прочитано данных: hello world"
"Количество байт: 11"
Пример с несколькими врайтерами
Давайте создадим несколько врайтеров и объединим их
с помощью io.MultiWriter:
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func main() {
data := []byte("abcde")
reader := bytes.NewReader(data)
var buf1, buf2 bytes.Buffer
multiWriter := io.MultiWriter(&buf1, &buf2, os.Stdout)
teeReader := io.TeeReader(reader, multiWriter)
res, err := io.ReadAll(teeReader)
if err != nil {
panic(err)
}
fmt.Printf("\nRead all: %s\n", string(res))
fmt.Printf("Buffer 1: %s\n", buf1.String())
fmt.Printf("Buffer 2: %s\n", buf2.String())
}
Результат выполнения кода:
"abcde"
"Read all: abcde"
"Buffer 1: abcde"
"Buffer 2: abcde"
Смотрите также
-
функцию
io.ReadAll,
которая читает все данные из ридера до конца -
функцию
io.MultiWriter,
которая объединяет несколько врайтеров в один -
функцию
io.Copy,
которая копирует данные из ридера во врайтер -
интерфейс
io.Reader,
который определяет базовый интерфейс для чтения данных