Разработка и Конфигурация · 11 мин
Как проверить наличие файла в папке в 1С
Как проверить наличие файла в папке в 1С: метод Файл.Существует(), работа с путями, проверка каталогов, примеры кода для тонкого и веб-клиента, типичные ошибки.
Проверка существования файла — одна из базовых операций при работе с файловой системой в 1С:Предприятие. Она нужна перед чтением данных из файла, перед записью, чтобы не перезаписать важный документ, и при обмене данными с внешними системами, когда файл может ещё не быть выгружен.
Во встроенном языке 1С для этого используется объект Файл и его метод Существует(). Подход одинаков для файлов и каталогов: создаётся объект с указанием пути, после чего вызывается метод проверки. Важно учитывать контекст исполнения — на клиенте и на сервере проверяются разные файловые системы.
Ниже разобраны основные сценарии: проверка файла и папки, поиск по маске, особенности клиент-серверного режима и типичные ошибки, из-за которых проверка возвращает «Ложь», хотя файл на месте.
Базовый способ: объект Файл и метод Существует()
Стандартный приём выглядит так: создаётся объект встроенного типа Файл, в конструктор которого передаётся полный путь, затем вызывается метод Существует(), возвращающий булево значение.
ФайлНаДиске = Новый Файл("C:\Обмен\Заказы.xml");
Если ФайлНаДиске.Существует() Тогда
Сообщить("Файл найден, размер: " + ФайлНаДиске.Размер());
Иначе
Сообщить("Файл не найден!");
КонецЕсли;
Объект Файл не требует, чтобы файл реально существовал — это просто описание пути. Поэтому создание объекта безопасно: ошибка возникнет только при попытке чтения или записи несуществующего файла, но не при проверке.
Через тот же объект доступны дополнительные свойства, полезные сразу после проверки: Размер(), ПолучитьВремяИзменения(), ЭтоКаталог(), Расширение, ИмяБезРасширения. Это позволяет не только убедиться в наличии файла, но и проверить, что он не пустой и изменялся недавно.
ФайлНаДиске = Новый Файл("C:\Обмен\Заказы.xml");
Если ФайлНаДиске.Существует() Тогда
Сообщить("Файл найден");
Иначе
Сообщить("Файл отсутствует");
КонецЕсли;Как отличить файл от папки
Метод Существует() возвращает «Истина» и для каталогов. Если задача — убедиться, что по пути находится именно файл, а не папка с таким же именем, нужна дополнительная проверка через ЭтоКаталог() или ЭтоФайл().
ФайлНаДиске = Новый Файл(Путь);
Если ФайлНаДиске.Существует() Тогда
Если ФайлНаДиске.ЭтоКаталог() Тогда
Сообщить("Это папка");
Иначе
Сообщить("Это файл");
КонецЕсли;
КонецЕсли;
Тот же приём применяется для проверки существования самой папки перед записью в неё файлов. Если каталога нет, его можно создать процедурой СоздатьКаталог() — она умеет создавать всю цепочку вложенных папок за один вызов и не вызывает ошибку, если каталог уже существует.
Поиск файлов в папке по маске
Когда точное имя файла неизвестно — например, файл выгружается с датой в имени — используется функция НайтиФайлы(). Она возвращает массив объектов Файл, соответствующих маске.
НайденныеФайлы = НайтиФайлы("C:\Обмен\", "*.xml");
Если НайденныеФайлы.Количество() > 0 Тогда
Для Каждого Найденный Из НайденныеФайлы Цикл
Сообщить(Найденный.Имя + " — " + Найденный.Размер() + " байт");
КонецЦикла;
Иначе
Сообщить("Файлов по маске не найдено");
КонецЕсли;
В маске допустимы символы (любое количество символов) и ? (один символ). Третьим параметром можно передать Истина для поиска во вложенных подкаталогах: НайтиФайлы(Путь, ".xlsx", Истина).
Учтите, что поиск по маске в папке с большим количеством файлов занимает заметное время, особенно по сети. Если имя файла известно точно, прямая проверка через Файл.Существует() работает быстрее.
Сравнение способов проверки
Подходит, когда известен точный путь. Быстро, но не ищет по маске.
Подходит для поиска по маске и перебора содержимого папки. Медленнее на больших каталогах.
Подходит, когда важна не только наличие, но и доступность файла для чтения. Код сложнее.
Клиент и сервер: где выполняется проверка
Ключевой момент в клиент-серверном режиме: код, выполняемый на сервере, проверяет файловую систему сервера 1С, а код на клиенте — компьютер пользователя. Путь C:\Обмен\file.xml в серверной процедуре указывает на диск сервера, а не на диск пользователя.
Поэтому перед написанием проверки определите, где физически лежит файл. Если пользователь выбирает файл на своём компьютере, проверку и чтение нужно выполнять в клиентском контексте, а затем передавать данные на сервер — например, через временное хранилище с помощью НачатьПомещениеФайла().
В тонком и веб-клиенте прямой доступ к файловой системе ограничен. Для работы с локальными файлами используется расширение работы с файлами: методы НачатьПодключениеРасширенияРаботыСФайлами() и асинхронные аналоги проверки — НачатьПоискФайлов(), а также проверка через НачатьВызовСуществует() объекта Файл.
Асинхронная проверка в тонком и веб-клиенте
В управляемых формах с отказом от модальности синхронный вызов Существует() на клиенте может быть недоступен. Вместо него используется асинхронный вариант с описанием оповещения.
&НаКлиенте
Процедура ПроверитьФайл(Команда)
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Оповещение = Новый ОписаниеОповещения("ПослеПроверкиСуществования", ЭтотОбъект);
ФайлНаДиске.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПроверкиСуществования(Существует, ДополнительныеПараметры) Экспорт
Если Существует Тогда
Сообщить("Файл на месте");
Иначе
Сообщить("Файл не найден");
КонецЕсли;
КонецПроцедуры
Такой подход требует подключённого расширения работы с файлами. Если оно не установлено, платформа предложит пользователю установить его — предусмотрите этот сценарий в коде, иначе проверка молча не выполнится.
- 1Определите, где лежит файл: на компьютере пользователя или на сервере
- 2Сформируйте полный путь, объединив каталог и имя файла
- 3Создайте объект Файл и вызовите Существует()
- 4При необходимости уточните ЭтоФайл()/ЭтоКаталог() и проверьте размер
- 5Обработайте отсутствие файла: сообщение пользователю или запись в журнал
Права доступа и сетевые пути
Проверка вернёт «Ложь», если у учётной записи, под которой работает код, нет доступа к папке — даже когда файл существует. На сервере 1С это обычно учётная запись службы агента сервера (по умолчанию — служебный пользователь USR1CV8), у которой часто нет прав на сетевые ресурсы и локальные диски пользователей.
Для сетевых путей используйте UNC-формат \\Сервер\Обмен\file.xml вместо подключённых сетевых дисков: буквы дисков существуют только в сессии конкретного пользователя и недоступны службе сервера 1С.
Если проверка упорно возвращает «Ложь», проверьте путь вручную от имени той же учётной записи, под которой работает сервер. Это самый быстрый способ отличить проблему прав доступа от ошибки в пути.
Склейка путей и переносимость кода
Не собирайте путь простой конкатенацией строк вида Каталог + "\" + ИмяФайла — при разделителе в конце каталога получится двойной слеш. В типовых конфигурациях для этого есть функции общих модулей (например, ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути() в БСП).
Для кроссплатформенности разделитель пути можно получать программно: ПолучитьРазделительПути(). Это важно, если сервер 1С работает на Linux, где используются прямые слеши и чувствительность к регистру имён файлов.
На Linux-платформе имя Data.xml и data.xml — разные файлы. Если обмен идёт между Windows и Linux, приводите имена к единому регистру при формировании и проверке, иначе файл, записанный одной системой, не будет найден другой.
Как проверить результат
Файл существует и путь корректен
Истина, но путь ведёт не туда — проверьте контекст клиент/сервер
Файла действительно нет
Файл есть, но нет прав доступа или неверный путь
Данные читаются без исключений
Ошибка доступа — файл заблокирован другим процессом
Проверка перед записью: защита от перезаписи
Обратный сценарий — проверка перед сохранением файла. Если файл с таким именем уже существует, запись может молча перезаписать его. Перед выгрузкой стоит проверить наличие и либо сформировать уникальное имя (например, добавив дату и время), либо запросить подтверждение у пользователя.
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
ПутьКФайлу = ФайлНаДиске.Путь + ФайлНаДиске.ИмяБезРасширения
+ "_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss")
+ ФайлНаДиске.Расширение;
КонецЕсли;
Также полезно проверять, что файл не пустой после записи: сравните Размер() с нулём. Это простой способ убедиться, что выгрузка действительно состоялась, особенно при работе с сетевыми ресурсами.
Что важно запомнить
Проверка наличия файла выполняется через Новый Файл(путь) и метод Существует(), поиск по маске — через НайтиФайлы(). Всегда учитывайте контекст исполнения (клиент или сервер), права учётной записи, UNC-пути для сетевых ресурсов и оборачивайте операции чтения/записи в обработку исключений.
Частые вопросы
Можно ли проверить файл без создания объекта Файл?
Да, для поиска по маске есть функция НайтиФайлы(), которая возвращает массив найденных файлов. Но для проверки конкретного известного пути объект Файл с методом Существует() — самый прямой и быстрый вариант.
Почему Существует() возвращает Ложь, хотя файл точно есть?
Чаще всего причины три: код выполняется на сервере, а файл лежит на компьютере пользователя; у учётной записи службы сервера нет прав на папку; в пути ошибка — лишний или недостающий слеш, неверная буква диска, другой регистр имени на Linux.
Как проверить, что папка пустая?
Вызовите НайтиФайлы(ПутьКПапке, "*") и проверьте, что возвращённый массив имеет нулевую длину. Предварительно убедитесь через ЭтоКаталог(), что путь указывает именно на папку.
Работает ли проверка в веб-клиенте?
Да, но только через асинхронные методы (НачатьПроверкуСуществования, НачатьПоискФайлов) и при установленном расширении работы с файлами в браузере. Синхронные вызовы файловой системы в веб-клиенте недоступны.
Как проверить файл на FTP или в облаке?
Объект Файл работает только с локальной и сетевой файловой системой. Для FTP используйте объект FTPСоединение с методом НайтиФайлы(), а для облачных хранилищ — их API через HTTP-запросы.
Что быстрее: Существует() или НайтиФайлы()?
Для точного пути быстрее Существует() — это одна прямая проверка. НайтиФайлы() перечисляет содержимое каталога, поэтому на больших или сетевых папках заметно медленнее и оправдан только при поиске по маске.