cpp

Преобразование кодировок

До этого момента мы работали с файлами в кодировке UTF-8. Однако файлы могут быть в различных кодировках. Например, в русской версии Windows файлы чаще всего сохранены в кодировке windows-1251. Чтобы иметь возможность выполнять преобразование кодировок нужно установить дополнительный пакет. Переходим в проект C:\book\packages и выполняем следующую команду:

C:\book\packages>go get -u golang.org/x/text
go get: added golang.org/x/text v0.3.7

Обратите внимание на содержимое файла go.mod, там появилась зависимость:

module exanple.com/mymodule

go 1.17

require golang.org/x/text v0.3.7 // indirect

Русские кодировки

Подключение пакета, предназначенного для преобразования кодировок, выглядит так:

import "golang.org/x/text/encoding/charmap"

Пакет содержит следующие основные объекты русских кодировок (полный список смотрите в документации):

var charmap.Windows1251 *charmap.Charmap
var charmap.CodePage866 *charmap.Charmap
var charmap.KOI8R *charmap.Charmap

Структура Charmap содержит два основных метода:

(*charmap.Charmap).NewEncoder() *encoding.Encoder
(*charmap.Charmap).NewDecoder() *encoding.Decoder

С помощью структуры Encoder выполняется преобразование данных из кодировки UTF-8 в кодировку объекта структуры Charmap. Структура Encoder содержит следующие методы:

  • String() — выполняет преобразование кодировки строки. Формат метода:
(*encoding.Encoder).String(s string) (string, error)

Метод возвращает два значения. Через первое значение доступна преобразованная строка. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример преобразования строки в кодировке UTF-8 в строку в кодировке windows-1251:

// import "golang.org/x/text/encoding/charmap"
utf8 := "строка"
encoder := charmap.Windows1251.NewEncoder()
win1251, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(win1251)) // [241 242 240 238 234 224]
  • Bytes() — выполняет преобразование кодировки байтового слайса. Формат метода:
(*encoding.Encoder).Bytes(b []byte) ([]byte, error)

Метод возвращает два значения. Через первое значение доступен преобразованный байтовый слайс. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример:

utf8 := []byte("строка")
encoder := charmap.Windows1251.NewEncoder()
win1251, err := encoder.Bytes(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(win1251) // [241 242 240 238 234 224]
  • Writer() — возвращает объект io.Writer с помощью которого можно записывать преобразованные данные в поток вывода. Формат метода:
(*encoding.Encoder).Writer(w io.Writer) io.Writer

Пример записи строки в файл в кодировке windows-1251:

func test() {
   file, err := os.Create(`C:\book\test.txt`)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer file.Close()
   encoder := charmap.Windows1251.NewEncoder()
   win1251 := encoder.Writer(file)
   _, err = io.WriteString(win1251, "Строка1\nСтрока2")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println("Операция выполнена успешно")
}

С помощью структуры Decoder выполняется преобразование данных из кодировки объекта структуры Charmap в кодировку UTF-8. Структура Decoder содержит следующие методы:

  • String() — выполняет преобразование кодировки строки. Формат метода:
(*encoding.Decoder).String(s string) (string, error)

Метод возвращает два значения. Через первое значение доступна преобразованная строка. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример преобразования строки в кодировке windows-1251 в строку в кодировке UTF-8:

// import "golang.org/x/text/encoding/charmap"
win1251 := "\xf1\xf2\xf0\xee\xea\xe0"
decoder := charmap.Windows1251.NewDecoder()
utf8, err := decoder.String(win1251)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // строка
  • Bytes() — выполняет преобразование кодировки байтового слайса. Формат метода:
(*encoding.Decoder).Bytes(b []byte) ([]byte, error)

Метод возвращает два значения. Через первое значение доступен преобразованный байтовый слайс. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример:

win1251 := []byte{241, 242, 240, 238, 234, 224}
decoder := charmap.Windows1251.NewDecoder()
utf8, err := decoder.Bytes(win1251)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(string(utf8)) // строка
  • Reader() — возвращает объект io.Reader с помощью которого можно считывать преобразованные данные из потока ввода. Формат метода:
(*encoding.Decoder).Reader(r io.Reader) io.Reader

Пример чтения из файла, сохраненного в кодировке windows-1251:

func test() {
   file, err := os.Open(`C:\book\test.txt`)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer file.Close()
   decoder := charmap.Windows1251.NewDecoder()
   win1251 := decoder.Reader(file)
   utf8, err := io.ReadAll(win1251)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(utf8))
}

Кодировка UTF-16

Для работы с кодировкой UTF-16 нужно использовать функцию UTF16() из пакета golang.org/x/text/encoding/unicode. Формат функции:

unicode.UTF16(e unicode.Endianness,
              b unicode.BOMPolicy) encoding.Encoding

Первый параметр задает порядок следования байтов. Можно указать константы unicode.LittleEndian или unicode.BigEndian. Второй параметр задает политику обработки метки порядка байтов (BOM). Можно указать следующие константы:

  • unicode.UseBOM — метка порядка байтов используется;
  • unicode.IgnoreBOM — метка порядка байтов игнорируется;
  • unicode.ExpectBOM — метка порядка байтов используется для переопределения кодировки по умолчанию.

Функция UTF16() возвращает объект Encoding, который содержит знакомые уже нам методы:

(encoding.Encoding).NewEncoder() *encoding.Encoder
(encoding.Encoding).NewDecoder() *encoding.Decoder

Пример преобразования строки в кодировке UTF-8 в строку в кодировке UTF-16LE с BOM:

// import "golang.org/x/text/encoding/unicode"
utf8 := "строка"
encoder := unicode.UTF16(unicode.LittleEndian,
                         unicode.UseBOM).NewEncoder()
utf16le, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(utf16le))
// [255 254 65 4 66 4 64 4 62 4 58 4 48 4]

Пример преобразования строки в кодировке UTF-16LE в строку в кодировке UTF-8:

utf16le := "\xff\xfeA\x04B\x04@\x04>\x04:\x040\x04"
decoder := unicode.UTF16(unicode.LittleEndian,
                         unicode.UseBOM).NewDecoder()
utf8, err := decoder.String(utf16le)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // строка

Кодировка UTF-32

Для работы с кодировкой UTF-32 нужно использовать функцию UTF32() из пакета golang.org/x/text/encoding/unicode/utf32. Формат функции:

utf32.UTF32(e utf32.Endianness, b utf32.BOMPolicy) encoding.Encoding

Первый параметр задает порядок следования байтов. Можно указать константы utf32.LittleEndian или utf32.BigEndian. Второй параметр задает политику обработки метки порядка байтов (BOM). Можно указать следующие константы:

  • utf32.UseBOM — метка порядка байтов используется;
  • utf32.IgnoreBOM — метка порядка байтов игнорируется;
  • utf32.ExpectBOM — метка порядка байтов используется для переопределения кодировки по умолчанию.

Функция UTF32() возвращает объект Encoding, который содержит знакомые уже нам методы:

(encoding.Encoding).NewEncoder() *encoding.Encoder
(encoding.Encoding).NewDecoder() *encoding.Decoder

Пример преобразования строки в кодировке UTF-8 в строку в кодировке UTF-32LE с BOM:

// import "golang.org/x/text/encoding/unicode/utf32"
utf8 := "тест"
encoder := utf32.UTF32(utf32.LittleEndian,
                       utf32.UseBOM).NewEncoder()
utf32le, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(utf32le))
// [255 254 0 0 66 4 0 0 53 4 0 0 65 4 0 0 66 4 0 0]

Пример преобразования строки в кодировке UTF-32LE в строку в кодировке UTF-8:

utf32le := "\xff\xfe\x00\x00B\x04\x00\x005\x04\x00\x00A\x04" +
           "\x00\x00B\x04\x00\x00"
decoder := utf32.UTF32(utf32.LittleEndian,
                       utf32.UseBOM).NewDecoder()
utf8, err := decoder.String(utf32le)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // тест

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp