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

Интерфейс io.WriteCloser в Go используется для типов, которые поддерживают как запись данных, так и закрытие ресурса. Он объединяет методы Write и Close. Метод Write принимает срез байтов и возвращает количество записанных байтов и ошибку. Метод Close закрывает ресурс и освобождает связанные с ним системные ресурсы. Этот интерфейс часто используется при работе с файлами, сетевыми соединениями и другими потоками данных, которые требуют явного закрытия.

Синтаксис

gotype WriteCloser interface {
  Write(p []byte) (n int, err error)
  Close() error
}

Пример работы с файлом

Давайте создадим файл, запишем в него строку и закроем с использованием io.WriteCloser:

gopackage main

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

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

  var wc io.WriteCloser = file
  bytes, err := wc.Write([]byte("Hello, WriteCloser"))
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("Записано байт: %d\n", bytes)
  // закрываем явно
  if err := wc.Close(); err != nil {
    fmt.Println(err)
  }
}

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

go"Записано байт: 19"

Пример с буферизированным писателем

Интерфейс io.WriteCloser может быть реализован и другими типами, например, bufio.Writer, который буферизирует запись, но не имеет метода Close. Обернем его в io.NopCloser для соответствия интерфейсу:

gopackage main

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

func main() {
  file, err := os.Create("buffered.txt")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer file.Close()

  bufWriter := bufio.NewWriter(file)
  var wc io.WriteCloser = io.NopCloser(bufWriter)

  _, err = wc.Write([]byte("Buffered write"))
  if err != nil {
    fmt.Println(err)
    return
  }

  if err := bufWriter.Flush(); err != nil {
    fmt.Println(err)
  }
  if err := wc.Close(); err != nil {
    fmt.Println(err)
  }
  fmt.Println("Данные записаны")
}

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

go"Данные записаны"

Пример с сетевым соединением

Рассмотрим использование io.WriteCloser с сетевым подключением:

gopackage main

import (
  "fmt"
  "io"
  "net"
)

func main() {
  conn, err := net.Dial("tcp", "example.com:80")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer conn.Close()

  var wc io.WriteCloser = conn
  _, err = wc.Write([]byte("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"))
  if err != nil {
    fmt.Println(err)
    return
  }

  if err := wc.Close(); err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("Запрос отправлен")
}

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

go"Запрос отправлен"

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

  • интерфейс io.Writer,
    предназначенный для записи данных
  • интерфейс io.Closer,
    предназначенный для закрытия ресурсов
  • интерфейс io.ReadCloser,
    объединяющий чтение и закрытие
  • функцию io.NopCloser,
    возвращающую WriteCloser без операции закрытия