При разработке интеграций в 1С одна из частых и неприятных проблем — неизвестная кодировка входящих текстовых данных. Файлы, выгрузки из старых программ, API-ответы. Данные могут приходить в разных кодировках. В результате нередко получаем беспорядочный набор символов, непригодный для дальнейшего использования. К сожалению, штатными средствами 1С определить кодировку «на лету» невозможно.
На одном из проектов я столкнулся с задачей определения кодировки и корректного чтения файлов с нестандартной кодировкой. И ожидаемо столкнулся с тем, что в платформе 1C нет удобного механизма автоматического определения кодировки данных.
Стандартных средств в платформе немного. В БСП (Библиотека стандартных подсистем) реализован простой анализатор кодировок, поддерживающий наиболее распространённые варианты для русского языка: UTF-8 (с BOM и без), windows-1251, ibm866 и др.
В большинстве случаев этого набора достаточно для решения типовых задач.
Однако у данного подхода есть ограничения: список поддерживаемых кодировок не является исчерпывающим, а сам алгоритм анализа основан на сопоставлении символов кириллицы и латиницы.
Из-за этого в ряде случаев кодировка определяется некорректно или не определяется вовсе — особенно в файлах с числовыми данными, спецсимволами или разметкой.
В результате приходится либо подбирать кодировку вручную, либо усложнять обработку входных данных.
Функция БСП для определения кодировки:
// Автоматически определяет и возвращает кодировку текстового файла.
//
// Параметры:
// ДанныеДляАнализа - ДвоичныеДанные, Строка - данные для определения кодировки или адрес данных.
// Расширение - Строка - расширение файла.
//
// Возвращаемое значение:
// Строка
//
РаботаСФайламиСлужебныйКлиентСервер.ОпределитьКодировкуДвоичныхДанных(ДанныеДляАнализа, Расширение) Экспорт
Задача восполнения недостатка в функционале языка 1С в работе с кодировками показалась мне интересной, и чтобы закрыть этот пробел, я реализовал внешнюю компоненту, которая:
- автоматически определяет кодировку входных данных
- конвертирует их в UTF-8
- работает на Windows и Linux
- подключается как стандартная native-компонента 1С
Реализация выполнена на Rust с использованием проверенных библиотек, применяемых в браузерных движках.
- chardetng - служит для определения кодировки по байтовой статистике данных, а не только по вхождению алфавитных символов. Лучше справляется с контентом, где часть символов искажена, — отдельные ошибки меньше влияют на общий вывод.
- encoding_rs - выполняет непосредственно конвертацию байтов в кодировке, определённой на предыдущем шаге, в строку UTF-8. Поддерживает весь набор кодировок из стандарта Encoding Standard (WHATWG), поэтому справляется с любой известной кодировкой.
Во внешней компоненте реализованы две функции:
КонверторКодировки(ДвоичныеДанные) - функция принимает двоичные данные кодировку которых определить и Возвращает строку в UTF-8 независимо от исходной кодировки.
КодировкаДанных(ДвоичныеДанные) - функция принимает двоичные данные и возвращает имя определённой кодировки переданных данных.
Компонента может быть подключена как на 32-, так и на 64-разрядных системах Windows и Linux.

Подключение компоненты стандартное для native-внешних компонент. Внешняя компонента упакована в zip-архив. В примере внешняя компонента загружена в макет обработки с типом "двоичные данные".
Тестирование проводилось на платформе 8.3.27
&НаКлиенте
Асинх Процедура ПодключитьВнешнююКомпонентуНаКлиенте(ИмяФайла)
СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86_64 Тогда
Подключена = Ждать ПодключитьВнешнююКомпонентуАсинх("Обработка.Энкодер.Макет.ВнешняяКомпонента", "Encoder1c", ТипВнешнейКомпоненты.Native);
Если Не Подключена Тогда
Попытка
Ждать УстановитьВнешнююКомпонентуАсинх("Обработка.Энкодер.Макет.ВнешняяКомпонента");
Подключена = Ждать ПодключитьВнешнююКомпонентуАсинх("Обработка.Энкодер.Макет.ВнешняяКомпонента", "Encoder1c", ТипВнешнейКомпоненты.Native);
Если Не Подключена Тогда
ВызватьИсключение("Ошибка подключения внешней компоненты");
КонецЕсли;
Исключение
ВызватьИсключение("Ошибка подключения внешней компоненты");
КонецПопытки;
КонецЕсли;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Внешняя компонена не поддерживается для операционной системы";
Сообщение.Сообщить();
Возврат;
КонецЕсли;
ОбъектВК = Новый("Addin.Encoder1c.Encoder1c");
ЧтениеДанных = Новый ЧтениеДанных(ИмяФайла);
БуферДвоичныхДанных = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(БуферДвоичныхДанных);
ДанныеФайла = Ждать ОбъектВК.КонверторКодировки(ДвоичныеДанные);
КодировкаДанных = Ждать ОбъектВК.КодировкаДанных(ДвоичныеДанные);
КонецПроцедуры
&НаСервере
Процедура ПодключитьВнешнююКомпонентуНаСервере(АдресФайла)
Если Не ПодключитьВнешнююКомпоненту("Обработка.Энкодер.Макет.ВнешняяКомпонента", "Encoder1c", ТипВнешнейКомпоненты.Native) Тогда
ВызватьИсключение("Ошибка подключение внешней компоненты");
Возврат;
КонецЕсли;
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайла);
ОбъектВК = Новый("Addin.Encoder1c.Encoder1c");
ДанныеФайла = ОбъектВК.КонверторКодировки(ДвоичныеДанные);
КодировкаДанных = ОбъектВК.КодировкаДанных(ДвоичныеДанные);
КонецПроцедуры
Итоги
Компонента закрывает пробел, который штатные средства 1С и типовой анализатор БСП не всегда способны решить: надёжное автоматическое определение кодировки на данных любого объёма и состава, с конвертацией в UTF-8 «из коробки», на клиенте и на сервере, под Windows и Linux.
Вступайте в нашу телеграмм-группу Инфостарт