Как перекодировать Windows-1251 в UTF8 в Go без страданий • Ivan Feofanov
Ниже история одной моей довольно забавной ошибки. Воистину, программист никогда не заскучает; даже имея в руках идеальный инструмент, он сможет применить его неправильно. Что уж говорить об инструментах неидеальных?
Может показаться удивительным, но в просвещённом 2020-ом году всё ещё существуют разработчики, которые полагают, что нет ничего криминального в использовании кодировки windows-1251 при отдаче с эндпойнта API контента, содержащего кириллицу. Бог им судья, мне же пришлось искать способ этот самый контент безболезненно конвертнуть в благословенный юникод.
Забегая вперёд скажу, что задача, по сути, была примитивнейшая, однако я был бы не я, если бы не устроил себе цирк на ровном месте.
Итак, берём входящие байты и конвертим их в юникод (обработка ошибок и прочие закрытия body убраны для краткости).
dec := charmap.Windows1251.NewDecoder() out, _ := dec. Bytes(a) var meter dmc.Meter _ = json.Unmarshal(out, &meter) log.Print(meter.MeterName)
Что я ожидал увидеть? “ЭЛЕКТРОСНАБЖЕНИЕ”(я кажется, не упоминал, что работаю в ЖЭКе). А что я увидел? “пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ”
Признаться, результат меня озадачил и я кинулся искать, где и то пошло не так, однако все предлагаемые гуглом способы давали неизменно один и тот же результат. Начальник едко отметил, что процесс у меня идемпотентный — какой бы способ перекодировки не применялся, получается неизменно говно, и ушёл домой, я же остался чесать в затылке.
Тут меня осенило — если от смены способа перекодировки результат не меняется, значит, проблема прячется где-то в другом месте. Минут пятнадцать я пытался понять, могут ли разработчики того самого API присылать в хедере кодировку Windows-1251, а в тексте что-либо другое, однако Postman убедил меня, что, по крайней мере, тут всё честно — контент закодирован именно в Windows-1251.
Тогда я решил проследить весь путь данных, от получения до вывода в консоль и почти сразу принялся драть волосы из бороды, проклиная собственную тупость.Следите за руками. Контент приходит в формате json, такой вот структуры:
{ "contents": [], "result": { "code": 1, "message": "some message" } }
Поскольку я использую строго типизированный Go, и меня больше интересует не служебная информация, а тот самый контент, то данные проходят следующую обработку (я опускаю нерелевантный заметке код):
type Result struct { Code int Message string } type Response struct { Contents []interface{} Result Result } content := [][]byte{} var response Response _ = json.Unmarshal(res_body, &response) for _, item := range response.Contents { item_bytes, _ := json.Marshal(item) content = append(content, item_bytes) }
И вот этот самый content
и есть то, с чем уже можно работать,
маршалить его в структуры, отправлять письмом на деревню дедушке, и т. д.,
но вот тут-то и спряталась ошибка: первый анмаршаллинг пришедших байтов
сконвертил кириллицу в совершенно нечитаемые иероглифы, поскольку
корректно он умеет работать только с юникодом. А далее я получившиеся
каракули собственноручно смаршалил в байты и попытался сконвертировать
заранее нечитаемые символы в юникод и вполне ожидаемо получил на
выходе именно его — говно на лопате.
Как понимаете, после того, как я перенёс перекодирования данных в самое начало, сразу после после их получения, ситуация исправилась:
resp, _ := client.Get(url) res_body, _ := ioutil.ReadAll(resp.Body) dec := charmap.Windows1251.NewDecoder() out, _ := dec.Bytes(res_body) content := [][]byte{} var response Response err = json.Unmarshal(out, &response) for _, item := range response.Contents { item_bytes, _ := json.Marshal(item) content = append(content, item_bytes) } // ---- var meter dmc.Meter _ = json.Unmarshal(out, &meter) log.Print(meter.MeterName) //--> ЭЛЕКТРОСНАБЖЕНИЕ
Надеюсь, эта заметка поможет вам избежать подобной ошибки.
из Windows-1251 в UTF-8 – Zencoder
Тема статьи — конвертация mp3-тегов, созданных в кодировке windows-1251, в кодировку utf-8, под управлением операционной системы Linux.
В чем проблема
Причина возникновения такого вопроса заключается в том, что я уже достаточно давно стал поклонником аудио-книг. И передачи “Модель для сборки” — в частности. И хотя сама передача уже давно закрыта, ее архивы в Интернете доступны для скачивания.
Дома у меня имеются только две операционные системы — Mac OS X 10.10 и Linux Mint 17 Cinnamon. И вот тут возникает небольшая проблема, связанная с тем, что Audacious под Linux и iTunes под Mac не отображают правильно мета-информацию проигрываемых mp3-файлов аудио-книг, если эти файлы созданы под Windows.
Другими словами, аудио-проигрыватель “читает” аудио-книгу, но вот понять визуально — какую, нельзя. Не видно названия книги, ее автора, имени чтеца. Происходит это потому, что оба вышеназванных проигрывателя не могут правильно отображать мета-данные mp3-файлов, если эти мета-данные созданы в кодировке windows-1251.
Как решить проблему
Решением вопроса является перекодировка мета-данных mp3-файлов, перевод символов из кодировки windows-1251 в кодировку utf-8, с которой умеют работать Audacious и iTunes.
Решение оказалось на удивление простое и “под рукой”. Популярный редактор mp3-тегов под Linux с названием EasyTAG в два счета справляется с задачей. Главное — нужно правильно настроить чтение mp3-тегов этой программой.
Последовательность действий по настройке EasyTAG
Устанавливаем программу EasyTAG
Переходим в настройки программы EasyTAG — “Edit — Preferences”
К окне настроек программы EasyTAG переходим на вкладку “ID3 Tag Settings”
Устанавливаем параметры программы EasyTAG так, как это показано на скриншоте:
Если описать двумя словами, то необходимо для “ID3v1 tags” выбрать кодировку Windows-1251, для “ID3v1 tags” выбрать кодировку utf-8. Для поля “Character Set for reading ID3 tags” также выбрать кодировку windows-1251.
Конвертация в программе EasyTAG
Когда программа EasyTAG настроена, то процесс конвертации mp3-тегов из кодировки windows-1251 в кодировку utf-8 выполнить проще простого.
Открываем в программе EasyTAG папку с коллекцией mp3-файлов, которые необходимо обработать (переконвертировать).
Выделяем в окне программы EasyTAG все эти файлы.
Сохраняем их.
Да, именно так — “открыл-сохранил”, ничего больше. И теперь Audacious вместе с iTunes прекрасно читают обработанные файлы музыки (и аудио-книг).
На этом все.
linuxeasytag
Красивая функция trackBy
Пример красивой функции trackBy для Angular. Функция понравилась своей лаконичностью:{% highlight typescript %}public trackByNumber = (_:…… Continue reading
ESLint: TypeError: this.
libOptions.parse is not a function Published on September 13, 2022Ubuntu — проблема с KVM Switch
Published on September 12, 2022Преобразование текстового файла в UTF-8 в командной строке Windows
спросил
Изменено 6 месяцев назад
Просмотрено 138 тысяч раз
Мне нужно преобразовать текстовый файл в формат UTF-8 через командную строку Windows. Это нужно сделать на другой машине, и у меня нет прав на установку программного обеспечения на эту машину. Мне нужно что-то вроде:
c:\notepad исходный файл целевой файл --encoding option
Есть ли утилита командной строки Windows, которая может это сделать?
- windows
- командная строка
- utf-8
Мне нужно преобразовать текстовый файл в формат utf-8 через командную строку Windows
. \Get-Content тест.txt | Set-Content-Кодировка utf8 test-utf8.txt
Дополнительная литература
- Преобразование из большинства кодировок в utf8 с помощью powershell
13
Использовать iconv
из пакета GNUWin32. Это намного быстрее, особенно если ваши файлы больше 1 Гб.
"C:\Program Files (x86)\GnuWin32\bin\iconv.exe" -f cp1251 -t utf-8 source.txt > result.txt
3
Вот для каждого преобразования файла *.text в файл *.sql:
foreach ($file в get-ChildItem *.txt) { Эхо $file.name Получить содержимое $file | Set-Content-Encoding utf8 ("$file.name" +".sql") }
1
Вы можете сделать это из командной строки следующим образом:
powershell -command "Get-Content.\test.txt" > test-utf8.txt
Оказывается, вывод вывода в файл из командной строки сохраняется как utf-8.
1
POWERSHELL: # Предполагается Windows PowerShell, используйте -Encoding utf8BOM с PowerShell Core. Для нескольких файлов:
ПЕРВОЕ РЕШЕНИЕ:
$files = Get-ChildItem c:\Folder1\ -Filter *.txt foreach ($ файл в $ файлах) { Get-Content $file.FullName | Set-Content "E:\Temp\Destination\$($file.Name)" -Кодировка utf8BOM }
ИЛИ, ВТОРОЕ РЕШЕНИЕ (для нескольких файлов):
get-item C:\Folder1*.* | foreach-object {get-content -Encoding utf8BOM $_ | out-file ("C:\Folder1" + $_.Name) - кодировка по умолчанию}
ИЛИ, ТРЕТЬЕ РЕШЕНИЕ: (только для 2 файлов)
$a = "C:/Folder1/TEST_ro.txt" $b = "C:/Папка1/TEST_ro-2.txt" (Get-Content-path $a) | Set-Content-Кодировка UTF8BOM-Путь $b
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания, политикой конфиденциальности и политикой использования файлов cookie.основной пакет | |
импорт ( | |
«фмт» | |
«golang.org/x/text/encoding/charmap» | |
) | |
основная функция () { | |
для я := 0; я <= 255; я++ { | |
символ := uint8(i) | |
ориг := []uint8{charnum} | |
utf8: = DecodeWindows1251 (оригинал) | |
win1251: = EncodeWindows1251 (utf8) | |
, если строка (оригинал)! = строка (win1251) { | |
fmt. Printf(«О~.. Ошибка в charnum 0x%x\n», i) | |
fmt.Printf(«(оригинал, utf8, win1251)\n») | |
fmt.Printf(«строка: %s, %s, %s\n», строка(оригинал), строка(utf8), строка(win1251)) | |
fmt.Printf(«в кавычках: %+q, %+q, %+q\n», строка (оригинал), строка (utf8), строка (win1251)) | |
fmt.Printf(«hex: % x, % x, % x\n», строка (оригинал), строка (utf8), строка (win1251)) | |
} | |
} | |
} | |
функция DecodeWindows1251(ba []uint8) []uint8 { | |
дек := charmap. Оставить комментарий
|