Как найти файл по маске имени в заданной папке в 1С

Программист IT и автоматизация бизнеса
← На главную

При разработке механизмов обмена данными или обработок по импорту документов часто возникает задача: проверить наличие файла в конкретной папке, имя которого соответствует определенному шаблону. Например, нам нужно найти все файлы, названия которых начинаются на префикс «АВ». В 1С:Предприятии 8 для этих целей предусмотрены мощные встроенные инструменты работы с файловой системой.

В этой статье мы подробно разберем, как правильно организовать поиск, какие существуют нюансы при работе на разных операционных системах и как сделать ваш код максимально производительным и надежным.

Базовый метод поиска: использование функции НайтиФайлы

Самый простой и эффективный способ решить задачу — использовать встроенную функцию НайтиФайлы(). Она позволяет не просто перебирать всё содержимое папки, а сразу отфильтровать нужные объекты с помощью маски поиска. Рассмотрим, как это выглядит на практике.

Проанализируем пример кода, который решает задачу автора темы:


ПутьКПапке = "C:\MyFiles\";
МаскаПоиска = "АВ*"; // Ищем всё, что начинается на АВ
НайденныеФайлы = НайтиФайлы(ПутьКПапке, МаскаПоиска, Ложь);

Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
    Сообщить("Найден файл: " + ТекущийФайл.Имя);
КонецЦикла;

Разберем параметры функции НайтиФайлы() по шагам:

  1. Путь: Строка, содержащая полный адрес каталога, в котором производится поиск.
  2. Маска: Шаблон имени файла. Использование символа * (звездочка) означает любое количество произвольных символов. Маска "АВ*" найдет и «АВ_отчет.xlsx», и «АВ123.txt», и просто «АВ».
  3. Рекурсия (Булево): Если передать Истина, система будет искать файлы не только в указанной папке, но и во всех вложенных подпапках. В нашем случае мы передаем Ложь, так как ищем строго в конкретном каталоге.

Важность фильтрации: файл или каталог?

В ходе обсуждения на форуме возник важный вопрос: а что если в папке окажется подкаталог, чье имя тоже начинается на «АВ»? Например, папка с названием «АВ_Архив». Функция НайтиФайлы() вернет и файлы, и каталоги, подходящие под маску.

Выясним, как гарантированно отличить файл от папки. Для этого у объекта типа Файл, который возвращается в цикле, есть специальные методы. Использование проверки на наличие расширения (точки в имени) — ненадежно, так как папки тоже могут иметь точки в названиях, а файлы могут быть без расширений.

Рассмотрим правильный алгоритм проверки:


Для Каждого ОбъектПоиска Из НайденныеФайлы Цикл
    Если ОбъектПоиска.ЭтоФайл() Тогда
        // Это точно файл, выполняем действия
        ОбработатьФайл(ОбъектПоиска.ПолноеИмя);
    ИначеЕсли ОбъектПоиска.ЭтоКаталог() Тогда
        // Это папка, ее мы пропускаем
        Продолжить;
    КонецЕсли;
КонецЦикла;

Использование методов ЭтоФайл() и ЭтоКаталог() делает ваш код устойчивым к особенностям именования объектов в файловой системе.

Оптимизация поиска с помощью масок

Посмотрим на ситуацию, когда нам нужно более точное соответствие. В 1С поддерживаются два основных спецсимвола в масках:

Если мы точно знаем, что после «АВ» должно идти ровно 3 цифры и расширение .txt, мы можем использовать маску "АВ???.txt". Это значительно ускорит работу системы, если в папке находятся тысячи файлов, так как фильтрация произойдет на уровне операционной системы, а не внутри цикла 1С.

Особенности работы в разных операционных системах

Нужно учитывать, где именно выполняется код — на клиенте под Windows или на сервере под управлением Linux. Проанализируем ключевое различие: чувствительность к регистру.

В ОС Windows поиск по маске "АВ*" найдет и «ав_файл», и «АВ_ФАЙЛ». Однако в Linux регистр имеет значение. Если вы ищете файлы на Linux-сервере, маска "АВ*" не найдет файлы, начинающиеся со строчных букв «ав». В таких случаях рекомендуется либо приводить имена к одному регистру (если это возможно при создании файлов), либо выполнять поиск по всем файлам (маска "*") и проверять условие внутри цикла с помощью функции НРег().


// Универсальный способ для Linux (чувствителен к производительности)
ВсеФайлы = НайтиФайлы(Путь, "*", Ложь);
Для Каждого Файл Из ВсеФайлы Цикл
    Если Лев(ВРег(Файл.Имя), 2) = "АВ" Тогда
        // Файл найден независимо от регистра
    КонецЕсли;
КонецЦикла;

Современный подход: Асинхронные методы

Если вы разрабатываете решение для тонкого или веб-клиента (особенно для версий платформы 8.3.18 и выше), использование синхронного метода НайтиФайлы() может привести к «зависанию» интерфейса. Рассмотрим асинхронный аналог — НайтиФайлыАсинх().

Этот метод работает через механизм «Обещаний» (Promises). Он позволяет программе продолжать работу, пока диск или сеть отвечают на запрос. Это особенно критично при работе с сетевыми папками или медленными носителями.

Обработка исключительных ситуаций

При работе с внешними ресурсами всегда существует риск возникновения ошибок. Самые частые причины: отсутствие прав доступа к папке или физическое отсутствие пути. Хорошей практикой считается использование конструкции Попытка ... Исключение.


Попытка
    НайденныеФайлы = НайтиФайлы(ПутьКПапке, "АВ*");
Исключение
    ЗаписьЖурналаРегистрации("Поиск файлов", УровеньЖурналаРегистрации.Ошибка, , , 
        "Ошибка доступа к пути: " + ОписаниеОшибки());
    Возврат; // Или другая обработка ошибки
КонецПопытки;

Также перед поиском можно проверить существование самого каталога, используя объект Файл:


ПроверкаКаталога = Новый Файл(ПутьКПапке);
Если Не ПроверкаКаталога.Существует() Тогда
    Сообщить("Указанный путь не найден!");
КонецЕсли;

Подведем итоги

Для поиска файлов по префиксу в 1С наиболее правильно использовать функцию НайтиФайлы() с корректно настроенной маской. Это избавляет от необходимости перебирать лишние данные в цикле. Не забывайте использовать методы ЭтоФайл() для проверки типа объекта и учитывайте особенности операционной системы сервера, на которой исполняется ваш код.

← На главную