Работа с внешними текстовыми файлами — одна из самых частых задач при организации обмена данными между 1С и сторонними системами. Основная сложность здесь заключается не в самой записи данных, а в правильном выборе и обработке кодировки. В этой статье мы подробно разберем, как программно управлять кодировками, в чем разница между основными форматами и как избежать появления «кракозябр» при загрузке данных.
Для простых задач, связанных с небольшими файлами, в 1С традиционно используется объект ТекстовыйДокумент. Он позволяет быстро прочитать или записать файл, однако обладает меньшей гибкостью по сравнению со специализированными потоковыми объектами.
Рассмотрим пример, когда нам нужно сохранить данные в кодировке UTF-8, а затем прочитать их. Проанализируем следующий код:
// Запись файла
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.УстановитьТекст("Пример текста для экспорта");
ТекстДок.Записать(ПутьКФайлу, КодировкаТекста.UTF8);
// Чтение файла
ТекстДок.Прочитать(ПутьКФайлу, КодировкаТекста.UTF8);
Сообщить(ТекстДок.ПолучитьТекст());
Важно помнить, что если при методе Прочитать не указать кодировку, 1С попытается определить ее автоматически. Однако автоматика часто ошибается, если в файле отсутствуют специальные маркеры (BOM), поэтому всегда рекомендуется указывать кодировку явно.
Для профессиональной разработки и работы с большими объемами данных лучше использовать объекты ЧтениеТекста и ЗаписьТекста. Они работают быстрее, так как не загружают весь файл в память целиком, а позволяют читать его построчно или частями.
Разберем, как реализовать загрузку файла из сообщения автора темы, используя ЧтениеТекста:
ПутьКФайлу = "C:\temp\data.txt";
// Создаем объект для чтения с явным указанием кодировки UTF-8
ФайлЧтения = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
// Читаем файл построчно до самого конца
СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
Пока СтрокаТекста <> Неопределено Цикл
// Обрабатываем полученную строку
ОбработатьСтрокуЗагрузки(СтрокаТекста);
СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
КонецЦикла;
ФайлЧтения.Закрыть();
Этот метод считается более надежным, так как вы управляете процессом чтения на каждом этапе. В конструкторе объекта ЧтениеТекста можно указать не только системную константу, но и числовой код страницы (например, "windows-1251" или 1251).
В обсуждении на форуме часто мелькают термины ANSI и OEM. Выясним причину их использования и ключевые отличия:
КодировкаТекста.UTF8.Windows-1251. Используется большинством старых Windows-приложений. В 1С — КодировкаТекста.ANSI.CP866 (DOS). Она до сих пор встречается в банковских выписках, файлах обмена с кассовым оборудованием и терминалами. В 1С — КодировкаТекста.OEM.Если вы получаете файл и видите вместо букв непонятные символы, проанализируем ситуацию: скорее всего, файл записан в одной кодировке, а вы пытаетесь прочитать его в другой. Если файл в UTF-8 прочитать как ANSI, русские буквы превратятся в двойные наборы странных знаков.
Один из критически важных нюансов при работе с UTF-8 — это наличие или отсутствие BOM. BOM — это три невидимых байта в начале файла (EF BB BF), которые сообщают программам, что файл сохранен именно в UTF-8.
Стандартный метод 1С Записать(..., КодировкаТекста.UTF8) всегда добавляет BOM. Если внешняя система (например, какой-нибудь старый веб-сервер или скрипт на Python) не ожидает этих символов, она выдаст ошибку «неверный формат». Если вам нужно записать UTF-8 без BOM, используйте следующий прием через ДвоичныеДанные:
// Текст, который нужно записать
ТекстДляЗаписи = "Данные без BOM";
// Преобразуем строку в двоичные данные в кодировке UTF-8
// Третий параметр Ложь отключает добавление BOM
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ТекстДляЗаписи, "UTF-8", Ложь);
// Записываем на диск
ДвоичныеДанные.Записать(ПутьКФайлу);
Иногда возникают ситуации, когда файл уже прочитан в «сыром» виде или кодировка неизвестна заранее. В платформе 8.3 существует мощный механизм работы через двоичные данные, который позволяет гибко перекодировать текст.
Рассмотрим, как прочитать файл, если мы заранее не знаем, в какой он кодировке, но хотим попробовать разные варианты:
// Читаем весь файл в двоичном виде
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Вариант 1: Пытаемся получить строку как UTF-8
СтрокаUTF8 = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеФайла, "UTF-8");
// Вариант 2: Пытаемся получить строку как Windows-1251
СтрокаANSI = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеФайла, "windows-1251");
Этот подход позволяет избежать ошибок объекта ЧтениеТекста, если файл поврежден или содержит нетипичные символы. Мы можем проанализировать полученную строку программно и выбрать ту, в которой больше читаемых символов.
Подведем итог и составим алгоритм действий при работе с текстовыми файлами в 1С:
UTF-8. Если со старым банком или DOS-программой — выбирайте OEM.ДвоичныеДанные.ЧтениеТекста и ЗаписьТекста всегда вызывайте метод Закрыть(), иначе файл останется занятым операционной системой, и его нельзя будет удалить или переместить.Следуя этим правилам, мы обеспечим стабильную работу механизмов импорта и экспорта данных, а наши пользователи никогда не столкнутся с проблемой нечитаемых текстов.