Как в 1С сохранить текстовый файл или CSV в кодировке UTF-8 без BOM

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции с внешними сервисами, веб-сайтами или импорте файлов CSV во внешние системы разработчики часто сталкиваются с требованием: файл должен быть сохранен строго в кодировке UTF-8 без сигнатуры BOM (Byte Order Mark, три байта EF BB BF в начале файла). Если использовать стандартный объект платформы ЗаписьТекста с перечислением КодировкаТекста.UTF8, 1С автоматически добавляет эти байты в начало файла. Выясним причину такого поведения и разберем несколько проверенных способов формирования файлов без метки порядка байтов.

Проанализируем ситуацию: в конструкторе объекта ЗаписьТекста нет прямого булевого параметра для отключения BOM (в отличие, например, от объекта ЗаписьXML). Рассмотрим подробнее практические варианты обхода этого ограничения.

Способ 1. Использование строкового параметра кодировки «CESU-8»

В платформе 1С параметр кодировки в конструкторе ЗаписьТекста может принимать не только значения системного перечисления КодировкаТекста, но и строковые наименования различных кодировок. Одной из таких поддерживаемых кодировок является CESU-8.

Посмотрим на пример кода:


ПутьКФайлу = "D:\1\1.csv";
Текст = Новый ЗаписьТекста(ПутьКФайлу, "CESU-8", , Истина);
Текст.ЗаписатьСтроку("Колонка1;Колонка2;Колонка3");
Текст.ЗаписатьСтроку("Значение1;Значение2;Значение3");
Текст.Закрыть();

Разберем важный нюанс этого способа: кодировка CESU-8 сохраняет файл без добавления BOM-маркера и полностью совпадает со стандартным UTF-8 для символов базовой многоязычной плоскости (коды символов до U+FFFF — стандартная кириллица, латиница, знаки препинания и цифры). Однако если в ваших данных могут встретиться символы за пределами BMP (например, эмодзи или редкие специальные символы), кодировка CESU-8 сформирует их в виде суррогатных пар, что может вызвать ошибку парсинга на стороне строгого приемника.

Способ 2. Использование функции «ПолучитьДвоичныеДанныеИзСтроки» (рекомендуемый штатный способ)

Начиная с современных версий платформы 1С:Предприятие 8.3 (8.3.10 и выше), доступен штатный глобальный метод, который позволяет напрямую управлять добавлением BOM при преобразовании строки в двоичные данные. Если объем выгружаемых данных позволяет сформировать результирующий текст в оперативной памяти, этот способ является наиболее чистым и надежным.

Разберем по шагам реализацию данного подхода:

  1. Формируем полный текст CSV в обычной строковой переменной.
  2. Преобразуем строку в двоичные данные с указанием кодировки КодировкаТекста.UTF8 и явным отключением BOM через системное перечисление ИспользованиеByteOrderMark.НеИспользовать (или значение Ложь).
  3. Записываем полученные двоичные данные на диск.

Посмотрим на пример:


// 1. Формируем текст файла
ТекстCSV = "Код;Наименование;Цена" + Символы.ПС + "001;Товар 1;100" + Символы.ПС;

// 2. Получаем двоичные данные без сигнатуры BOM
ДанныеФайла = ПолучитьДвоичныеДанныеИзСтроки(ТекстCSV, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// 3. Сохраняем файл на диск
ДанныеФайла.Записать("D:\1\1.csv");

Способ 3. Предварительное создание пустого файла

Интересная особенность механизма ЗаписьТекста заключается в том, что платформа 1С добавляет сигнатуру BOM только при создании нового файла. Если файл уже существует на диске (пусть даже с нулевым размером), и мы открываем его в режиме дозаписи, BOM в начало файла не помещается.

Рассмотрим, как реализовать этот прием:


ПутьКФайлу = "D:\1\1.csv";

// Шаг 1. Создаем пустой файл нулевого размера
Запись = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.ANSI);
Запись.Закрыть();

// Шаг 2. Открываем существующий файл с флагом дозаписи (параметр ДописыватьВКонец = Истина)
Запись = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8, , Истина);
Запись.ЗаписатьСтроку("Колонка1;Колонка2;Колонка3");
Запись.ЗаписатьСтроку("Данные1;Данные2;Данные3");
Запись.Закрыть();

Способ 4. Программное удаление первых 3 байт через Base64

Если файл уже сформирован стандартными средствами и занимает большой объем, мы можем программно вырезать метку BOM из начала готового файла. В кодировке Base64 три байта BOM (EF BB BF) всегда преобразуются в первые четыре символа 77u/.

Посмотрим на пример удаления BOM через двоичные данные:


ПутьКФайлу = "D:\1\1.csv";

ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
СтрокаBase64 = Base64Строка(ДвоичныеДанныеФайла);

// Проверяем наличие сигнатуры BOM в начале Base64-строки
Если Лев(СтрокаBase64, 4) = "77u/" Тогда
    СтрокаBase64 = Сред(СтрокаBase64, 5);
    ОчищенныеДанные = Base64Значение(СтрокаBase64);
    ОчищенныеДанные.Записать(ПутьКФайлу);
КонецЕсли;

Подведем итог: для разовых выгрузок небольших отчетов и файлов оптимально использовать метод ПолучитьДвоичныеДанныеИзСтроки с параметром ИспользованиеByteOrderMark.НеИспользовать. Если же требуется потоковая запись больших объемов данных построчно через ЗаписьТекста, можно применить указание строковой кодировки "CESU-8" или трюк с предварительным созданием пустого файла.

← На главную