Как исправить ошибку кодировки (кракозябры) при чтении XML-файла в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При интеграции систем 1С с веб-сайтами (например, при обмене заказами или каталогами товаров) разработчики часто сталкиваются с проблемой, когда текстовые данные на русском языке загружаются некорректно. Вместо понятных названий и реквизитов в систему попадают «кракозябры» вида "ДатаФорРмыйР". При этом на самом сайте и даже при открытии файла через обычный текстовый блокнот в Windows всё отображается отлично.

В этой статье мы подробно разберем, почему возникает эта ошибка, как устроены механизмы кодирования текста в разных средах и рассмотрим несколько вариантов решения проблемы — от быстрого исправления «в лоб» до архитектурно правильных подходов с использованием встроенных объектов платформы 1С:Предприятие.

Выясняем причину: почему возникают «кракозябры»?

Основная причина появления нечитаемых символов — несовпадение кодировки, в которой файл был записан на веб-сервере, и кодировки, которую платформа 1С использует для чтения по умолчанию. Кириллический текст на современных веб-ресурсах практически всегда формируется в кодировке UTF-8. В то же время операционная система Windows в русскоязычной локализации и объект 1С ТекстовыйДокумент по умолчанию пытаются прочесть текстовые файлы в кодировке Windows-1251 (ANSI).

В кодировке UTF-8 каждый символ русского алфавита кодируется двумя байтами, а в Windows-1251 — одним байтом. Когда 1С считывает двухбайтовые символы UTF-8, предполагая, что это однобайтовая кодировка Windows-1251, она интерпретирует каждый отдельный байт как самостоятельный символ. Именно из-за этого русская буква «Д» превращается в два непонятных знака, образуя характерные «кракозябры».

Возникает логичный вопрос: почему файлы, созданные самой 1С, читаются нормально? Дело в специальной сигнатуре, которая называется BOM (Byte Order Mark).

Почему чтение XML через ТекстовыйДокумент — это антипаттерн?

Рассмотрим фрагмент кода, из-за которого часто возникает данная проблема:


ФайлXML = Новый ТекстовыйДокумент;
ФайлXML.Прочитать(Параметры.ФайлЗагрузки);
СтрокаXML = ФайлXML.ПолучитьТекст();

Использование объекта ТекстовыйДокумент для работы с XML-структурами крайне нежелательно по следующим причинам:

  1. Высокое потребление оперативной памяти: Файл загружается в память целиком в виде одной гигантской строки. Если размер файла выгрузки составляет десятки или сотни мегабайт (например, полный каталог товаров), это может привести к критическому расходу ресурсов сервера и аварийному завершению работы процесса 1С.
  2. Лишнее двойное преобразование: Сначала платформа тратит ресурсы на преобразование двоичных данных в текст, а затем парсеру XML приходится повторно обрабатывать эту строку для разбора структуры.

Ниже мы разберем правильные варианты решения этой задачи.

Способ 1. Быстрое исправление (указание кодировки при чтении текста)

Если вам необходимо временно сохранить текущую логику работы с объектом ТекстовыйДокумент, достаточно явно передать кодировку во втором параметре метода Прочитать(). Платформа перестанет пытаться угадать кодировку по BOM-маркеру и принудительно применит UTF-8.

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


ФайлXML = Новый ТекстовыйДокумент;
// Явно указываем кодировку UTF-8 во втором параметре метода
ФайлXML.Прочитать(Параметры.ФайлЗагрузки, КодировкаТекста.UTF8);
СтрокаXML = ФайлXML.ПолучитьТекст();

После добавления системного перечисления КодировкаТекста.UTF8 файлы без BOM-маркера начнут считываться корректно, и кириллица примет нормальный вид.

Способ 2. Лучшая практика — использование объекта ЧтениеXML

Для правильной и производительной работы с XML-документами в платформе 1С предусмотрен специализированный объект — ЧтениеXML. Он работает по принципу последовательного потокового чтения (аналог SAX-парсера) и обладает встроенными механизмами автоматического распознавания кодировок.

Посмотрим на пример правильной реализации:


ЧтениеФайлаXML = Новый ЧтениеXML;
// Объект самостоятельно проанализирует заголовок xml-файла и определит кодировку
ЧтениеФайлаXML.ОткрытьФайл(Параметры.ФайлЗагрузки);

Пока ЧтениеФайлаXML.Прочитать() Цикл
    // Здесь выполняется потоковый разбор узлов XML-документа
    Если ЧтениеФайлаXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        ИмяУзла = ЧтениеФайлаXML.Имя;
        // Обрабатываем данные узла
    КонецЕсли;
КонецЦикла;

ЧтениеФайлаXML.Закрыть();

Почему этот способ является приоритетным:

Способ 3. Использование современных объектов ЧтениеТекста и ДвоичныеДанные

Если перед вами стоит задача прочесть файл именно как обычную текстовую строку (без разбора XML-структуры), в современных версиях платформы 1С:Предприятие 8.3 реализованы более эффективные альтернативы устаревшему объекту ТекстовыйДокумент.

Вариант А. Использование объекта ЧтениеТекста

Этот объект спроектирован специально для неинтерактивного программного чтения текстовых файлов. Он работает быстрее и потребляет значительно меньше ресурсов:


ПутьКФайлу = Параметры.ФайлЗагрузки;
ФайлЧтения = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
СтрокаXML = ФайлЧтения.Прочитать();
ФайлЧтения.Закрыть();

Вариант Б. Чтение через ДвоичныеДанные (для версий 1С 8.3.10 и выше)

Для быстрого и безопасного преобразования файлов в строку без риска возникновения проблем с BOM-маркерами можно использовать методы работы с двоичными данными:


ПутьКФайлу = Параметры.ФайлЗагрузки;
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Преобразуем двоичные данные напрямую в строку с указанием кодировки UTF-8
СтрокаXML = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеФайла, КодировкаТекста.UTF8);

Этот метод работает чрезвычайно быстро на уровне платформы и исключает любые ошибки интерпретации байтов.

Если же вам в будущем понадобится записать текстовый файл для отправки на сайт строго в формате UTF-8 без BOM, вы можете использовать метод обратного преобразования с отключением вывода BOM-маркера:


ДвоичныеДанныеДляЗаписи = ПолучитьДвоичныеДанныеИзСтроки(СтрокаXML, КодировкаТекста.UTF8, Ложь);
ДвоичныеДанныеДляЗаписи.Записать(ПутьКФайлу);

Параметр Ложь в функции ПолучитьДвоичныеДанныеИзСтроки гарантирует, что в начале файла не будет лишней сигнатуры BOM, и веб-сервер примет файл без каких-либо ошибок парсинга.

Резюме

Для предотвращения ошибок кодировки при интеграции 1С с веб-ресурсами придерживайтесь следующих правил:

← На главную