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

Интерфейс io.RuneReader предназначен для чтения Unicode-символов (рун) из потока данных. Основной метод ReadRune считывает один символ, возвращая его значение в виде rune, размер в байтах и ошибку, если она произошла. Этот интерфейс особенно полезен при работе с текстовыми файлами, содержащими многобайтовые символы, такие как UTF-8.

Метод ReadRune возвращает три значения: считанную руну, количество байт (от 1 до 4) и ошибку. Если достигнут конец файла, возвращается специальная ошибка io.EOF. Для работы с интерфейсом обычно используется структура os.File, которая реализует io.RuneReader.

Синтаксис

gotype RuneReader interface {
  ReadRune() (r rune, size int, err error)
}

Пример

Откроем файл и прочитаем из него один символ:

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()

  r, size, err := file.ReadRune()
  if err != nil {
    fmt.Println("Error reading rune:", err)
    return
  }

  fmt.Printf("rune: %c, size: %d", r, size)
}

Результат выполнения кода (если в файле записан символ 'A'):

go"rune: A, size: 1"

Пример

Прочитаем все руны из файла до конца:

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()

  for {
    r, _, err := file.ReadRune()
    if err == io.EOF {
      break
    }
    if err != nil {
      fmt.Println("Error reading rune:", err)
      return
    }
    fmt.Printf("%c", r)
  }
}

Результат выполнения кода (если в файле записано "Привет"):

go"Привет"

Пример

Обработаем ошибку при чтении из пустого файла:

gopackage main

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

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

  r, _, err := file.ReadRune()
  if err == io.EOF {
    fmt.Println("End of file reached")
  } else if err != nil {
    fmt.Println("Unexpected error:", err)
  } else {
    fmt.Printf("Read rune: %c", r)
  }
}

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

go"End of file reached"

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

  • интерфейс io.Reader,
    базовый интерфейс для чтения байтов из потока
  • интерфейс io.ByteReader,
    предназначенный для чтения отдельных байтов
  • функцию io.ReadAll,
    которая читает все данные из потока до конца
  • структуру os.File,
    которая реализует интерфейс io.RuneReader