Работа с текстовыми файлами в системе 1С:Предприятие часто кажется тривиальной задачей, пока мы не сталкиваемся с распределенными средами. Одной из наиболее запутанных проблем является появление «кракозябр», иероглифов или знаков вопроса вместо русского текста при использовании тонкого клиента через веб-сервер (IIS или Apache). При этом в файловом варианте или при запуске через толстый клиент всё может работать идеально.
В данной статье мы подробно разберем, почему возникает эта ситуация, проанализируем механизмы работы кодировок в серверной среде и рассмотрим несколько эффективных способов решения проблемы.
Прежде всего, давайте разберем ситуацию. Когда программный код выполняется «НаСервере» в контексте веб-сервера, он работает от имени системной учетной записи (например, IUSR или IIS AppPool\DefaultAppPool). В отличие от обычного пользователя, у системной учетной записи могут быть свои настройки региональных стандартов (System Locale).
Если для системы языком программ, не поддерживающих Юникод, установлен английский (US), то стандартная константа КодировкаТекста.ANSI будет интерпретироваться как кодовая страница Windows-1252. Для русского языка нам необходима страница Windows-1251. В результате такого несовпадения кириллические символы превращаются в набор нечитаемых знаков или вопросительных меток.
Рассмотрим первый и самый фундаментальный способ — приведение региональных настроек сервера к единому стандарту. Это поможет, если вы не хотите менять программный код во множестве обработок.
Проанализируем ситуацию: теперь при обращении к методам ЧтениеТекста или ЗаписьТекста с параметром ANSI, система будет использовать корректную русскую кодовую страницу даже в контексте IIS.
Положиться на системные настройки — это хороший шаг, но для надежной разработки мы рекомендуем всегда явно указывать кодировку в коде 1С. Использование КодировкаТекста.ANSI делает ваш код зависимым от окружения. Давайте посмотрим на пример, как сделать код более стабильным.
Вместо использования системных констант, укажем строку кодировки явно:
// Ненадежный способ, зависящий от настроек сервера
ТекстЧтения = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.ANSI);
// Надежный способ с явным указанием кодовой страницы
ТекстЧтения = Новый ЧтениеТекста(ПутьКФайлу, "windows-1251");
Аналогично поступим при записи файла. Разберем пример создания текстового документа:
// Принудительно задаем кодировку при создании файла
ТекстЗаписи = Новый ЗаписьТекста(ПутьКФайлу, "windows-1251");
ТекстЗаписи.ЗаписатьСтроку("Пример русского текста");
ТекстЗаписи.Закрыть();
Важный момент: использование строки "windows-1251" гарантирует, что 1С проигнорирует региональные настройки сервера и применит нужную таблицу символов.
Как отметил автор исходной темы, переход на UTF-16 часто решает проблему мгновенно. Почему это происходит? В кодировках Юникод (особенно в UTF-16) практически всегда используется BOM (Byte Order Mark) — специальная метка в начале файла, которая сообщает любой программе (включая 1С на сервере), в каком формате представлены данные.
Рассмотрим, как правильно работать с UTF-8, чтобы избежать проблем при чтении на разных серверах:
// Запись в формате UTF-8 с BOM
Запись = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Данные в Юникоде");
Запись.Закрыть();
Если вы читаете файл, созданный сторонней системой, которая не добавила BOM, 1С на веб-сервере может снова «споткнуться». В этом случае используйте явное указание кодировки "UTF-8" при чтении, даже если файл кажется стандартным.
Проанализируем самый продвинутый способ, который полностью исключает влияние настроек веб-сервера и операционной системы. Этот метод заключается в чтении файла как набора байтов с последующим преобразованием в строку.
Разберем по шагам, как это реализовать:
ДвоичныеДанные.ЧтениеДанных для преобразования байтов в текст с точным указанием кодировки.Посмотрим на пример кода:
// Читаем файл как бинарный объект
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Создаем поток для чтения
Поток = Новый ПотокВПамяти(ДвоичныеДанныеФайла);
Чтение = Новый ЧтениеДанных(Поток, "windows-1251");
// Получаем весь текст целиком
РезультатТекст = Чтение.ПрочитатьТекст();
Чтение.Закрыть();
Поток.Закрыть();
Этот подход считается наиболее профессиональным, так как объекты ЧтениеДанных и ЗаписьДанных предоставляют более гибкий контроль над потоками информации, чем старые объекты ЧтениеТекста.
Иногда корень проблемы лежит в настройках самого веб-сервера IIS, который может принудительно изменять кодировку ответов или запросов. Выясним, где это можно проверить:
UTF-8 или Inherit. Если там принудительно стоит западноевропейская кодировка, её нужно изменить.Если ваша база 1С доступна через веб-клиент или тонкий клиент через HTTP, старайтесь выполнять чтение файлов на стороне клиента, если это технически возможно. Прочитав текст на клиентском компьютере (где настройки локали гарантированно верны для пользователя), вы можете передать уже готовую Строку на сервер для дальнейшей обработки. Это избавит вас от необходимости настраивать каждый сервер, на котором может быть развернута база.
Подводя итог, мы выяснили, что основная причина иероглифов — это неявное использование системной локали сервера. Используя явное указание кодировки "windows-1251" или переходя на современные методы работы с двоичными данными, вы обеспечите стабильную работу вашей конфигурации в любых условиях эксплуатации.