Разработка и Конфигурация · 9 мин
Как получить каталог файла в 1С
Как получить каталог файла в 1С: разбор пути через СтрНайти, работа с объектом Файл, отличия Windows и Linux, типовые ошибки и готовые примеры кода.
Задача получить каталог файла в 1С возникает постоянно: при сохранении выгрузок рядом с исходным файлом, при обработке пакета документов из одной папки, при формировании отчётов с выгрузкой на диск. Встроенной функции «ПолучитьКаталогФайла» во встроенном языке платформы нет, поэтому каталог извлекают либо строковыми операциями, либо через объект Файл.
Оба подхода рабочие, но ведут себя по-разному: строковый разбор не обращается к диску и быстр, а объект Файл даёт дополнительные сведения, но требует осторожности на тонком клиенте и в веб-клиенте. Ниже — конкретные варианты кода, их ограничения и способы проверки результата.
Отдельная тонкость — разделитель пути. На Windows это обратный слэш «\», на Linux-сервере 1С — прямой «/». Если код должен работать на обеих платформах, разделитель нужно определять программно, иначе разбор пути «сломается» при переносе базы на другой сервер.
Что именно считается каталогом файла
Полный путь к файлу состоит из каталога (пути к папке) и имени файла с расширением. Например, в пути C:\Выгрузки\Отчеты\отчет.xlsx каталог — это C:\Выгрузки\Отчеты\, а имя файла — отчет.xlsx. Задача — отделить одно от другого.
Важный нюанс: файл с полным путём может не существовать на диске — путь бывает просто строкой, полученной из настроек, реквизита справочника или ввода пользователя. Строковый разбор работает с любым путём, а обращение к диску за атрибутами — только с реально существующим файлом.
Способ 1: разбор строки через СтрНайти с поиском с конца
Самый надёжный и быстрый вариант — найти последнее вхождение разделителя и обрезать строку. Функция СтрНайти с направлением поиска СКонца возвращает позицию последнего слэша, после чего Лев() отсекает каталог.
Функция ПолучитьКаталогФайла(ПолныйПуть) Экспорт
Разделитель = ПолучитьРазделительПути();
Позиция = СтрНайти(ПолныйПуть, Разделитель, НаправлениеПоиска.СКонца);
Если Позиция = 0 Тогда
Возврат ""; // разделителя нет — передано только имя файла
КонецЕсли;
Возврат Лев(ПолныйПуть, Позиция);
КонецФункции
Функция возвращает каталог вместе с завершающим разделителем — это удобно, потому что к результату можно сразу «приклеить» новое имя файла: Каталог + "результат.xml". Если разделитель в конце не нужен, используйте Лев(ПолныйПуть, Позиция - 1).
Каталог = ПолучитьКаталогФайла("C:\Выгрузки\отчет.xlsx");
// Результат: C:\Выгрузки\
НовыйФайл = Каталог + "архив.zip";Обработайте крайние случаи: пустая строка, путь без разделителя (только имя файла), путь, заканчивающийся на разделитель (это уже каталог, а не файл). В последнем случае функция вернёт исходную строку — обычно это корректно, но зависит от логики вашей обработки.
Способ 2: объект Файл и свойство Путь
Объект Файл предоставляет готовые свойства: Путь (каталог без имени файла), Имя (имя с расширением), ИмяБезРасширения, Расширение. Код получается короче и читаемее.
Файл = Новый Файл("C:\Выгрузки\Отчеты\отчет.xlsx");
Каталог = Файл.Путь; // C:\Выгрузки\Отчеты\
ИмяФайла = Файл.Имя; // отчет.xlsx
Расширение = Файл.Расширение; // .xlsx
Конструктор Новый Файл не требует, чтобы файл существовал на диске — свойства пути разбираются строково. Однако на тонком и веб-клиенте работа с файловой системой ограничена: обращение к локальным путям возможно только в режиме модальных вызовов или после подключения расширения работы с файлами. На сервере ограничений нет, но пути будут серверными, а не клиентскими — это частая причина ошибок в клиент-серверном режиме.
Учёт разделителя пути на Windows и Linux
Если база работает только на Windows, можно искать «\» напрямую. Но при кластере на Linux или при смешанной среде (сервер на Linux, клиенты на Windows) зашитый разделитель приведёт к ошибкам: СтрНайти не найдёт «\» в пути вида /opt/1c/data/file.xml и вернёт 0.
Функция ПолучитьРазделительПути() возвращает разделитель той системы, где выполняется код. Учтите: на сервере и на клиенте разделители могут отличаться, поэтому разбирайте путь там, где он был получен. Если путь пришёл от клиента на сервер — передавайте вместе с ним разделитель клиента или нормализуйте путь заранее.
Сравнение способов
Сравнение вариантов
Универсально, работает с любой строкой пути, не зависит от контекста выполнения. Требует вручную обрабатывать крайние случаи.
Короткий читаемый код, сразу даёт имя, расширение и путь. На тонком и веб-клиенте ограничен, требует осторожности в клиент-серверном режиме.
Подходит, когда нужны все уровни вложенности пути. Избыточен, если нужен только каталог, и требует склейки массива обратно.
Для большинства задач достаточно первого варианта. Объект Файл оправдан, когда помимо каталога нужны имя без расширения или проверка существования через метод Существует().
Проверка результата и типичные ошибки
После получения каталога полезно убедиться, что он существует и доступен на запись, особенно если дальше планируется сохранение файла. Для этого создайте объект Файл от каталога и вызовите Существует(), а для проверки записи — попробуйте создать временный файл и удалить его.
Как проверить результат
Содержит путь с завершающим разделителем
Пустая строка — в исходном пути не было разделителя
Файл.Существует() возвращает Истина
Ложь — путь указан неверно или сетевая папка недоступна
На Windows — «\», на Linux — «/»
Смешанные разделители в одном пути — признак ручной склейки строк
Практические сценарии применения
Сохранение результата рядом с исходным файлом
Типовая задача обработок: пользователь выбрал файл, результат нужно положить в ту же папку. Получите каталог, добавьте новое имя, проверьте доступность записи — и только потом сохраняйте.
- 1Получите полный путь от пользователя через ДиалогВыбораФайла или из реквизита
- 2Извлеките каталог функцией ПолучитьКаталогФайла
- 3Проверьте, что каталог не пустой и существует
- 4Склейте каталог с новым именем файла
- 5Сохраните результат и сообщите пользователю итоговый путь
Обход всех файлов в каталоге
Если нужно обработать все файлы папки, используйте НайтиФайлы(Каталог, "*.xml") — функция вернёт массив объектов Файл, у каждого уже есть свойства ПолноеИмя и Путь. Второй параметр — маска, третий (Истина) включает поиск во вложенных папках.
Выносите функцию получения каталога в общий модуль с признаком «Сервер» и «Вызов сервера» — тогда один и тот же код будет доступен из любых обработок, и не придётся дублировать разбор пути в каждой процедуре.
Что важно запомнить
Каталог извлекается поиском последнего разделителя через СтрНайти с направлением СКонца либо свойством Путь объекта Файл. Разделитель получайте программно, разбирайте путь в том контексте, где он получен, и проверяйте результат перед записью файлов.
Частые вопросы
Есть ли в 1С готовая функция для получения каталога файла?
Отдельной встроенной функции нет. Ближайший готовый вариант — объект Файл со свойством Путь. В типовых конфигурациях на БСП есть аналогичные функции в общих модулях работы с файлами, но они внутри используют те же строковые операции.
Как получить каталог, если путь введён пользователем вручную и может содержать ошибки?
Сначала проверьте, что строка не пустая и содержит разделитель. После извлечения каталога создайте объект Файл и вызовите Существует() — это отсечёт опечатки в пути до попытки записи.
Почему на сервере код не находит файл, хотя на клиенте всё работает?
Потому что сервер 1С видит свою файловую систему, а не диски пользователя. Путь C:\Документы\... существует только на клиенте. Передавайте файл на сервер через временное хранилище (ПоместитьВоВременноеХранилище) и работайте с данными, а не с путём.
Как получить каталог на уровень выше (родительскую папку)?
Извлеките каталог файла, уберите завершающий разделитель и повторно примените ту же функцию к результату — получите родительскую папку. Каждая итерация поднимает на один уровень вверх.
Работает ли разбор пути в веб-клиенте?
Строковый разбор (СтрНайти, Лев) работает везде, включая веб-клиент, потому что не обращается к диску. Объект Файл в веб-клиенте требует подключения расширения работы с файлами и асинхронных вызовов.
Что вернёт функция, если передан сетевой путь вида \\server\share\file.txt?
Корректно вернёт \\server\share\ — последний разделитель находится перед именем файла независимо от того, локальный путь или сетевой. Учитывайте только, что доступ к сетевой папке проверяется отдельно и зависит от прав учётной записи, под которой работает 1С.