Ошибка io.ErrClosedPipe

Ошибка io.ErrClosedPipe возвращается функциями пакета io, когда выполняется операция чтения или записи в канал, который был закрыт. Эта ошибка чаще всего встречается при работе с синхронными каналами, созданными с помощью io.Pipe, когда одна сторона канала закрывается, а другая сторона продолжает пытаться выполнить операции чтения или записи. Ошибка информирует о том, что канал больше не может использоваться для передачи данных.

Синтаксис

govar ErrClosedPipe = errors.New("io: read/write on closed pipe")

Ошибка возвращается в качестве значения типа error при попытке чтения или записи в закрытый канал.

Пример

Давайте создадим канал и закроем его, а затем попытаемся выполнить запись:

gopackage main

import (
  "fmt"
  "io"
)

func main() {
  // Создаем синхронный канал
  reader, writer := io.Pipe()

  // Закрываем канал для записи
  writer.Close()

  // Пытаемся записать данные в закрытый канал
  _, err := writer.Write([]byte("data"))
  if err != nil {
    fmt.Println(err)
  }
}

Результат выполнения кода:

go"io: read/write on closed pipe"

Пример

Рассмотрим ситуацию, когда одна горутина закрывает канал, а другая пытается читать из него:

gopackage main

import (
  "fmt"
  "io"
)

func main() {
  // Создаем канал
  reader, writer := io.Pipe()

  // Запускаем горутину для записи
  go func() {
    writer.Write([]byte("hello"))
    writer.Close()
  }()

  // Читаем данные из канала
  buf := make([]byte, 1024)
  n, err := reader.Read(buf)

  if err == io.ErrClosedPipe {
    fmt.Println("Канал был закрыт до завершения чтения")
  } else {
    fmt.Printf("Прочитано %d байт: %s\n", n, string(buf[:n]))
  }
}

Результат выполнения кода:

go"Прочитано 5 байт: hello"

Пример

Пример обработки ошибки при чтении из закрытого канала с использованием цикла:

gopackage main

import (
  "fmt"
  "io"
)

func main() {
  // Создаем канал
  reader, writer := io.Pipe()

  // Записываем данные и закрываем канал
  writer.Write([]byte("12345"))
  writer.Close()

  // Пытаемся прочитать данные из закрытого канала
  buf := make([]byte, 3)
  for {
    n, err := reader.Read(buf)
    if err != nil {
      if err == io.ErrClosedPipe {
        fmt.Println("Канал закрыт, чтение завершено")
      } else {
        fmt.Printf("Ошибка: %v\n", err)
      }
      break
    }
    fmt.Printf("Прочитано %d байт: %s\n", n, string(buf[:n]))
  }
}

Результат выполнения кода:

go"Прочитано 3 байт: 123"
"Прочитано 2 байт: 45"
"Канал закрыт, чтение завершено"

Смотрите также

  • функцию io.Pipe,
    которая создает синхронный канал для передачи данных
  • метод os.File.Close,
    который закрывает файл
  • ошибку os.ErrClosed,
    которая возникает при работе с закрытым файлом
  • интерфейс io.Closer,
    который предоставляет метод Close