Интерфейс io.ReadCloser

Интерфейс io.ReadCloser объединяет в себе два интерфейса: io.Reader и io.Closer. Он предоставляет методы Read для чтения данных из источника и Close для закрытия ресурса. Этот интерфейс часто используется при работе с файлами, сетевыми соединениями, HTTP-ответами и другими ресурсами, которые требуют явного освобождения после использования.

Синтаксис

gotype ReadCloser interface {
  Reader
  Closer
}

Методы интерфейса

Интерфейс io.ReadCloser включает два метода:

goRead(p []byte) (n int, err error)
Close() error

Метод Read считывает данные в байтовый срез и возвращает количество считанных байтов и ошибку. Метод Close закрывает ресурс и возвращает ошибку, если закрытие не удалось.

Пример с файлом

Давайте откроем файл для чтения и закроем его с помощью io.ReadCloser:

gopackage main

import (
  "fmt"
  "io"
  "os"
)

func main() {
  file, err := os.Open("example.txt")
  if err != nil {
    fmt.Println("Error opening file:", err)
    return
  }
  defer file.Close()

  var reader io.ReadCloser = file
  data := make([]byte, 100)
  n, err := reader.Read(data)
  if err != nil && err != io.EOF {
    fmt.Println("Error reading:", err)
    return
  }
  fmt.Println(string(data[:n]))
}

Пример с HTTP-ответом

Рассмотрим использование io.ReadCloser с HTTP-ответом:

gopackage main

import (
  "fmt"
  "io"
  "net/http"
  "os"
)

func main() {
  resp, err := http.Get("https://example.com")
  if err != nil {
    fmt.Println("Error making request:", err)
    return
  }
  defer resp.Body.Close()

  var body io.ReadCloser = resp.Body
  data, err := io.ReadAll(body)
  if err != nil {
    fmt.Println("Error reading body:", err)
    return
  }
  fmt.Println(string(data[:100]))
}

Пример с оберткой NopCloser

Функция io.NopCloser создает io.ReadCloser из io.Reader, который не выполняет никаких действий при закрытии:

gopackage main

import (
  "fmt"
  "io"
  "strings"
)

func main() {
  reader := strings.NewReader("abcde")
  readCloser := io.NopCloser(reader)
  defer readCloser.Close()

  data, err := io.ReadAll(readCloser)
  if err != nil {
    fmt.Println("Error reading:", err)
    return
  }
  fmt.Println(string(data))
}

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

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