Функция io.Pipe
Функция io.Pipe создает синхронный конвейер, который связывает
io.Reader и io.Writer. Она возвращает два значения:
*io.PipeReader и *io.PipeWriter. Данные, записанные
в writer, могут быть прочитаны из reader. Операции чтения и записи
блокируются до тех пор, пока другая сторона не завершит свою операцию,
что обеспечивает синхронную передачу данных.
Синтаксис
func Pipe() (*PipeReader, *PipeWriter)
Пример
Давайте создадим конвейер и запишем строку в writer, а затем прочитаем ее из reader:
package main
import (
"fmt"
"io"
)
func main() {
reader, writer := io.Pipe()
go func() {
defer writer.Close()
writer.Write([]byte("Hello, Pipe!"))
}()
data, err := io.ReadAll(reader)
if err != nil {
fmt.Printf("error: %v\n", err)
}
reader.Close()
fmt.Println(string(data))
}
Результат выполнения кода:
"Hello, Pipe!"
Пример
Давайте передадим данные через конвейер с использованием буфера и проверим, что чтение и запись синхронизированы:
package main
import (
"fmt"
"io"
"time"
)
func main() {
reader, writer := io.Pipe()
go func() {
defer writer.Close()
for i := 0; i < 3; i++ {
time.Sleep(100 * time.Millisecond)
writer.Write([]byte(fmt.Sprintf("message %d", i)))
}
}()
buf := make([]byte, 20)
for {
n, err := reader.Read(buf)
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("error: %v\n", err)
break
}
fmt.Printf("%s\n", string(buf[:n]))
}
reader.Close()
}
Результат выполнения кода:
"message 0"
"message 1"
"message 2"
Пример
Давайте используем io.Pipe для соединения двух горутин, где одна
генерирует данные, а другая их обрабатывает:
package main
import (
"fmt"
"io"
"strconv"
)
func main() {
reader, writer := io.Pipe()
go func() {
defer writer.Close()
for i := 1; i <= 5; i++ {
writer.Write([]byte(strconv.Itoa(i) + "\n"))
}
}()
go func() {
defer reader.Close()
buf := make([]byte, 10)
for {
n, err := reader.Read(buf)
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("error: %v\n", err)
break
}
fmt.Printf("processed: %s", string(buf[:n]))
}
}()
fmt.Scanln()
}
Результат выполнения кода:
"processed: 1"
"processed: 2"
"processed: 3"
"processed: 4"
"processed: 5"
Смотрите также
-
интерфейс
io.Reader,
который определяет методы для чтения данных -
интерфейс
io.Writer,
который определяет методы для записи данных -
функцию
io.Copy,
которая копирует данные из reader в writer -
функцию
io.ReadAll,
которая читает все данные из reader до EOF