Как решить проблему с кодировкой WIN1251 при чтении DBF в 1С на Linux-сервере

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

Перевод ИТ-инфраструктуры 1С:Предприятие на операционные системы семейства Linux (например, CentOS, RedHat, Rocky Linux) в связке с СУБД PostgreSQL — это отличный шаг в сторону оптимизации затрат на лицензирование и повышения стабильности работы системы. Однако на этом пути часто возникают неожиданные проблемы совместимости, связанные с обработкой устаревших форматов файлов данных. Одна из самых распространенных неполадок — появление «иероглифов» или «кракозябр» при попытке прочитать классические файлы обмена DBF (например, файлы выгрузки клиент-банков) на стороне сервера Linux.

В этой статье мы подробно проанализируем причины этой проблемы, разберем, почему переустановка PostgreSQL или изменение кодировок баз данных здесь не помогут, и рассмотрим практические варианты решения проблемы как на уровне программирования 1С, так и на уровне системного администрирования операционной системы CentOS.

Почему СУБД PostgreSQL ни при чем?

Первое заблуждение, с которым сталкиваются многие специалисты при возникновении проблем с кодировкой в трехзвенной архитектуре 1С, — это подозрения в сторону СУБД PostgreSQL. Администраторы начинают пересоздавать кластер баз данных под разные кодировки, пытаются принудительно внедрить локаль ru_RU.CP1251. Однако важно понимать ключевой принцип работы 1С с СУБД:

Таким образом, проблема кроется исключительно на этапе чтения файла сервером приложений 1С с использованием встроенного объекта XBase.

Выясняем техническую причину сбоя

Для чтения файлов формата DBF в платформе 1С:Предприятие используется объект XBase. Когда в коде прописывается свойство КодировкаXBase.ANSI, это указывает платформе на необходимость трансляции исходных байтов из кодовой страницы Windows-1251 (CP1251) в формат Unicode (который используется внутри платформы 1С).

На операционной системе Windows эта трансляция происходит автоматически силами системных API. На операционной системе Linux платформа 1С вынуждена использовать системную библиотеку локализации glibc и ориентироваться на текущую локаль запущенного процесса. Если процесс сервера 1С (демон ragent) работает в окружении с дефолтной локалью C или POSIX (или в чисто англоязычной локали en_US.UTF-8), то в системе просто отсутствуют необходимые таблицы сопоставления для кодировки CP1251. В результате этого встроенные функции перевода кодировок отрабатывают неверно, выдавая кракозябры вместо кириллических символов.

Давайте разберем три основных способа решения этой проблемы.

Способ 1. Чтение файла на стороне клиента Windows (Архитектурное решение)

Если в вашей компании пользователи работают с платформой 1С на операционной системе Windows, а сервер приложений крутится под управлением Linux, самым простым и надежным решением будет перенос операции чтения DBF-файла на сторону клиента. На клиентском компьютере Windows чтение кодировки CP1251 всегда отрабатывает корректно без дополнительных настроек ОС.

Рассмотрим по шагам, как это реализовать. Нам необходимо считать файл на клиенте, поместить данные во временную таблицу или структуру и передать эту таблицу на сервер для дальнейшей записи в базу данных.

Проанализируем пример кода, реализующий этот подход:


&НаСервере
Процедура ОбработатьДанныеНаСервере(ТаблицаДанных)
    // Преобразуем реквизит формы в значение для серверной обработки
    ТаблицаОбД = РеквизитФормыВЗначение("ТаблицаОбДанных");
    ТаблицаОбД.Очистить();
    
    Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
        НоваяСтрока = ТаблицаОбД.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ);
    КонецЦикла;
    
    // Возвращаем данные обратно на форму
    ЗначениеВРеквизитФормы(ТаблицаОбД, "ТаблицаОбДанных");
КонецПроцедуры

&НаКлиенте
Процедура ПрочитатьФайлНаКлиенте()
    ФайлDBF = Новый XBase;
    
    // Указываем кодировку ANSI (для кириллицы это CP1251)
    ФайлDBF.Кодировка = КодировкаXBase.ANSI;
    
    ПутьКФайлу = "C:\000.DBF";
    Попытка
        ФайлDBF.ОткрытьФайл(ПутьКФайлу, , Истина); // Открываем только для чтения
    Исключение
        ПоказатьПредупреждение(, "Не удалось открыть файл: " + ПутьКФайлу);
        Возврат;
    КонецПопытки;
    
    // Создаем таблицу для передачи данных на сервер
    ТаблицаПередачи = Новый ТаблицаЗначений;
    ТаблицаПередачи.Колонки.Добавить("Поле1");
    ТаблицаПередачи.Колонки.Добавить("Поле2");
    
    ФайлDBF.Первая();
    Пока Не ФайлDBF.ВКонце() Цикл
        Если Не ФайлDBF.ЗаписьУдалена() Тогда
            НоваяСтрока = ТаблицаПередачи.Добавить();
            НоваяСтрока.Поле1 = ФайлDBF.POS;
            НоваяСтрока.Поле2 = ФайлDBF.NNASP;
        КонецЕсли;
        ФайлDBF.Следующая();
    КонецЦикла;
    
    ФайлDBF.ЗакрытьФайл();
    
    // Передаем собранные данные на сервер
    ОбработатьДанныеНаСервере(ТаблицаПередачи);
КонецПроцедуры

Данный метод полностью исключает зависимость от настроек сервера Linux, так как вся низкоуровневая работа с DBF-форматом и кодировками происходит в гарантированно совместимой среде Windows.

Способ 2. Настройка локали для службы 1С под Linux (Административное решение)

Бывают ситуации, когда импорт DBF-файлов должен происходить в фоновом режиме (например, по расписанию через регламентное задание), когда никакого активного Windows-клиента нет. В этом случае нам придется заставить сервер 1С под Linux корректно понимать кириллическую кодировку ANSI.

Многие администраторы делают ошибку, настраивая локаль глобально через утилиту localectl set-locale LANG=ru_RU.cp1251. Сервер 1С запускается как системная служба через менеджер systemd, который изолирует переменные окружения и по умолчанию не передает глобальные настройки локали процессу ragent. Поэтому локаль нужно задать принудительно в конфигурационном юните службы 1С.

Разберем процесс настройки по шагам на примере CentOS:

  1. Откройте консоль сервера Linux с правами суперпользователя (root).
  2. Проверьте, установлена ли в системе русская локаль UTF-8. Для этого выполните команду: locale -a | grep ru В выводе вы должны увидеть строку ru_RU.utf8. Если ее нет, ее необходимо сгенерировать командой: localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
  3. Проверьте текущую локаль, под которой работает непосредственно пользователь usr1cv8: su -s /bin/bash -c "locale" usr1cv8
  4. Теперь перейдем к редактированию службы сервера 1С. Для этого воспользуемся встроенным механизмом переопределения конфигурации systemd: systemctl edit srv1cv83.service (Обратите внимание: имя службы может отличаться в зависимости от версии платформы, например, srv1cv83 или 1c-enterprise-8.3.22).
  5. В открывшемся текстовом редакторе добавьте секцию переопределения переменных окружения:
    
    [Service]
    Environment=LANG=ru_RU.UTF-8
    Environment=LC_ALL=ru_RU.UTF-8
    
    Примечание: Использовать локаль CP1251 в качестве основной системной локали для всей службы 1С крайне не рекомендуется, так как это может нарушить работу внутренних механизмов платформы. Локали ru_RU.UTF-8 вполне достаточно — она содержит в себе все необходимые таблицы перекодирования для ANSI/CP1251.
  6. Сохраните изменения и закройте файл. После этого обновите конфигурацию демонов systemd: systemctl daemon-reload
  7. Перезапустите службу сервера 1С для применения новых параметров окружения: systemctl restart srv1cv83.service

После выполнения этих шагов процесс сервера 1С получит доступ к таблицам перевода символов, и встроенный объект XBase на стороне сервера начнет корректно преобразовывать кириллицу из формата ANSI в Unicode.

Важная деталь: Особенности чувствительности к регистру в Linux

При переносе кода работы с DBF на Linux-сервер часто возникает сопутствующая ошибка: "Ошибка открытия файла". Помните, что операционная система Linux чувствительна к регистру символов в путях и именах файлов (Case Sensitivity).

Если на диске ваш файл называется import.dbf, а в коде 1С вы обращаетесь к нему как Import.DBF, Linux-сервер не сможет его найти и вызовет исключение. Всегда приводите имена файлов и пути к ним к точному соответствию на файловой системе.

Способ 3. Конвертация файла на лету перед загрузкой

Если у вас нет доступа к административным настройкам операционной системы сервера Linux, а загрузка должна выполняться на сервере, можно воспользоваться сторонними утилитами конвертации. Однако напрямую использовать популярную утилиту iconv для конвертации DBF-файла нельзя, так как DBF содержит бинарный заголовок, повреждение которого сделает файл нечитаемым.

Решением может стать написание небольшого скрипта на Python с использованием библиотеки dbfread или dbf, который будет предварительно читать DBF, переводить текстовые поля в UTF-8 и сохранять данные во временный текстовый файл (например, CSV или JSON) в кодировке UTF-8. Затем сервер 1С сможет легко прочитать этот текстовый файл с помощью объекта ЧтениеТекста, где кодировка указывается явно при чтении.

Подведем итог: для исправления кракозябр при чтении DBF на сервере 1С под Linux лучшим программистским решением является перенос разбора файла на сторону Windows-клиента, а лучшим системным решением — прописывание корректных переменных окружения LANG=ru_RU.UTF-8 в юнит службы 1С в systemd.

← На главную