Почему возникает ошибка при создании DBF-файла объектом XBase в папке с русскими буквами и как её исправить?

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

При разработке интеграций и выгрузок в формат DBF разработчики 1С нередко сталкиваются с ситуацией, когда метод СоздатьФайл() объекта XBase завершается аварийно, если в пути к каталогу присутствуют русские символы. При этом стандартные объекты платформы, такие как ТекстовыйДокумент или ЗаписьТекста, сохраняют файлы по тому же самому пути без каких-либо ошибок.

Рассмотрим пример кода, вызывающий исключение:


Х = Новый XBase;
Х.Поля.Добавить("pewpew", "N10");
// По английскому пути файл создается штатно:
// Х.СоздатьФайл("C:\ya kotolog\hash.dbf"); 

// По пути с кириллицей возникает ошибка:
Х.СоздатьФайл("C:\йа котолог\hash.dbf");

При выполнении такого кода платформа возвращает исключение: «Ошибка при вызове метода контекста (СоздатьФайл): Ошибка создания файла». Разберем детально причины такого поведения платформы 1С и операционной системы, а также рассмотрим все способы устранения проблемы.

Причина проблемы: архитектурные особенности объекта XBase

Проанализируем, почему возникает разница между поведением XBase и других объектов платформы:

  1. Использование устаревших интерфейсов Win32 ANSI API: Объект платформы XBase исторически спроектирован для совместимости со старыми стандартами и использует однобайтовые системные вызовы операционной системы для работы с файлами, в отличие от современных объектов (ТекстовыйДокумент, ДвоичныеДанные), использующих Юникод (CreateFileW).
  2. Зависимость от системной локали (System Locale): При передаче пути в метод СоздатьФайл() платформа преобразует строку из Юникода в текущую системную кодировку ОС (Active Code Page). Если сервер работает под управлением англоязычной Windows Server без установленной русской локали (кодовая страница Windows-1252), кириллические символы подменяются знаками вопроса (?). В результате файловая система не может найти или создать указанный путь.
  3. Ограничение свойства «Кодировка»: Свойство Кодировка объекта XBase (принимающее значения КодировкаXBase.ANSI или КодировкаXBase.OEM) определяет исключительно кодировку текстовых полей внутри самой таблицы DBF (Windows-1251 или CP866). На обработку пути файловой системы это свойство не оказывает никакого влияния.

Способ 1. Настройка системной локали Windows (рекомендуемое решение)

Выясним, как настроить операционную систему, чтобы служба сервера 1С корректно распознавала пути с кириллицей при ANSI-вызовах. Это системное решение, не требующее изменения программного кода и модулей БСП.

  1. Откроем Панель управления (Control Panel) и перейдем в раздел Региональные стандарты (Region).
  2. Перейдем на вкладку Дополнительно (Administrative).
  3. В блоке «Язык программ, не поддерживающих Юникод» (Language for non-Unicode programs) нажмем кнопку Изменить язык системы (Change system locale...).
  4. В выпадающем списке выберем Русский (Россия) / Russian (Russia). Флажок использования бета-версии UTF-8 включать не следует, так как это может нарушить работу сторонних драйверов и внешних компонент.
  5. Важный шаг для серверных служб: Если служба сервера 1С (ragent) выполняется под системной учетной записью (например, usr1cv8 или Network Service), нажмем кнопку Копировать параметры... (Copy settings...) на вкладке «Дополнительно» и установим флажки для копирования текущих региональных настроек в «Экран приветствия и системные учетные записи».
  6. Перезагрузим сервер для применения изменений кодовой страницы.

Способ 2. Использование коротких путей стандарта 8.3

Если изменить системную локаль на сервере невозможно по регламентным соображениям, мы можем воспользоваться короткими именами DOS (формат 8.3), которые состоят исключительно из символов ASCII и поддерживаются объектом XBase независимо от системной локали.

Посмотрим на пример получения короткого пути каталога через объект Scripting.FileSystemObject:


КаталогЮникод = "C:\йа котолог";

// Получаем короткий путь формата 8.3
ФСО = Новый COMОбъект("Scripting.FileSystemObject");
Папка = ФСО.GetFolder(КаталогЮникод);
КороткийПуть = Папка.ShortPath; // Вернет, например, "C:\BF47~1"

// Создаем DBF-файл по короткому пути
Х = Новый XBase;
Х.Поля.Добавить("pewpew", "N10");
Х.СоздатьФайл(КороткийПуть + "\hash.dbf");

Обратите внимание: Для работы данного способа каталог на диске должен существовать заранее, а на целевом томе NTFS должна быть включена генерация имен 8.3 (проверяется утилитой fsutil 8dot3name).

Способ 3. Создание во временном каталоге с последующим копированием

Разберем еще один программный обходной путь: создание файла во временной директории с гарантированно латинским путем (например, полученным через КаталогВременныхФайлов()) с последующим переносом средствами объекта Файл или функцией КопироватьФайл().


КаталогНазначения = "C:\йа котолог\";
ИмяФайла = "hash.dbf";
ВременныйПуть = КаталогВременныхФайлов() + ИмяФайла;

// Создаем и заполняем файл во временной папке с ASCII-путем
Х = Новый XBase;
Х.Поля.Добавить("pewpew", "N10");
Х.СоздатьФайл(ВременныйПуть);
Х.Записать();
Х.ЗакрытьФайл();

// Перемещаем файл в целевую директорию Юникод-совместимым методом платформы
КопироватьФайл(ВременныйПуть, КаталогНазначения + ИмяФайла);
УдалитьФайлы(ВременныйПуть);

Функция КопироватьФайл() платформы 1С работает через Юникод-интерфейсы и без проблем помещает готовый DBF-файл в каталог с русскими буквами.

Способ 4. Создание символьной ссылки (Junction)

В сценариях интеграции, когда путь жестко задан в сторонней системе или типовой подсистеме БСП, можно создать точку соединения NTFS (Junction) через командную строку Windows:

mklink /j "C:\yakotolog" "C:\йа котолог"

После создания точки соединения обращение через латинский путь C:\yakotolog\hash.dbf физически разместит файл внутри каталога C:\йа котолог\.

Особенности работы на серверах под управлением Linux

Проанализируем поведение серверного кода при переносе на Linux. Если аналогичная ошибка возникает на Linux-сервере 1С, причиной является некорректная локаль службы сервера. Для исправления ситуации необходимо убедиться, что в конфигурационном файле службы srv1cv8 заданы переменные окружения с поддержкой русской кодировки UTF-8 (например, LANG=ru_RU.UTF-8 и LC_ALL=ru_RU.UTF-8).

← На главную