При разработке интеграций и выгрузок в формат DBF разработчики 1С нередко сталкиваются с ситуацией, когда метод СоздатьФайл() объекта XBase завершается аварийно, если в пути к каталогу присутствуют русские символы. При этом стандартные объекты платформы, такие как ТекстовыйДокумент или ЗаписьТекста, сохраняют файлы по тому же самому пути без каких-либо ошибок.
Рассмотрим пример кода, вызывающий исключение:
Х = Новый XBase;
Х.Поля.Добавить("pewpew", "N10");
// По английскому пути файл создается штатно:
// Х.СоздатьФайл("C:\ya kotolog\hash.dbf");
// По пути с кириллицей возникает ошибка:
Х.СоздатьФайл("C:\йа котолог\hash.dbf");
При выполнении такого кода платформа возвращает исключение: «Ошибка при вызове метода контекста (СоздатьФайл): Ошибка создания файла». Разберем детально причины такого поведения платформы 1С и операционной системы, а также рассмотрим все способы устранения проблемы.
Проанализируем, почему возникает разница между поведением XBase и других объектов платформы:
XBase исторически спроектирован для совместимости со старыми стандартами и использует однобайтовые системные вызовы операционной системы для работы с файлами, в отличие от современных объектов (ТекстовыйДокумент, ДвоичныеДанные), использующих Юникод (CreateFileW).СоздатьФайл() платформа преобразует строку из Юникода в текущую системную кодировку ОС (Active Code Page). Если сервер работает под управлением англоязычной Windows Server без установленной русской локали (кодовая страница Windows-1252), кириллические символы подменяются знаками вопроса (?). В результате файловая система не может найти или создать указанный путь.Кодировка объекта XBase (принимающее значения КодировкаXBase.ANSI или КодировкаXBase.OEM) определяет исключительно кодировку текстовых полей внутри самой таблицы DBF (Windows-1251 или CP866). На обработку пути файловой системы это свойство не оказывает никакого влияния.Выясним, как настроить операционную систему, чтобы служба сервера 1С корректно распознавала пути с кириллицей при ANSI-вызовах. Это системное решение, не требующее изменения программного кода и модулей БСП.
ragent) выполняется под системной учетной записью (например, usr1cv8 или Network Service), нажмем кнопку Копировать параметры... (Copy settings...) на вкладке «Дополнительно» и установим флажки для копирования текущих региональных настроек в «Экран приветствия и системные учетные записи».Если изменить системную локаль на сервере невозможно по регламентным соображениям, мы можем воспользоваться короткими именами 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).
Разберем еще один программный обходной путь: создание файла во временной директории с гарантированно латинским путем (например, полученным через КаталогВременныхФайлов()) с последующим переносом средствами объекта Файл или функцией КопироватьФайл().
КаталогНазначения = "C:\йа котолог\";
ИмяФайла = "hash.dbf";
ВременныйПуть = КаталогВременныхФайлов() + ИмяФайла;
// Создаем и заполняем файл во временной папке с ASCII-путем
Х = Новый XBase;
Х.Поля.Добавить("pewpew", "N10");
Х.СоздатьФайл(ВременныйПуть);
Х.Записать();
Х.ЗакрытьФайл();
// Перемещаем файл в целевую директорию Юникод-совместимым методом платформы
КопироватьФайл(ВременныйПуть, КаталогНазначения + ИмяФайла);
УдалитьФайлы(ВременныйПуть);
Функция КопироватьФайл() платформы 1С работает через Юникод-интерфейсы и без проблем помещает готовый DBF-файл в каталог с русскими буквами.
В сценариях интеграции, когда путь жестко задан в сторонней системе или типовой подсистеме БСП, можно создать точку соединения NTFS (Junction) через командную строку Windows:
mklink /j "C:\yakotolog" "C:\йа котолог"
После создания точки соединения обращение через латинский путь C:\yakotolog\hash.dbf физически разместит файл внутри каталога C:\йа котолог\.
Проанализируем поведение серверного кода при переносе на Linux. Если аналогичная ошибка возникает на Linux-сервере 1С, причиной является некорректная локаль службы сервера. Для исправления ситуации необходимо убедиться, что в конфигурационном файле службы srv1cv8 заданы переменные окружения с поддержкой русской кодировки UTF-8 (например, LANG=ru_RU.UTF-8 и LC_ALL=ru_RU.UTF-8).