При разработке механизмов обмена данными или обработок по импорту документов часто возникает задача: проверить наличие файла в конкретной папке, имя которого соответствует определенному шаблону. Например, нам нужно найти все файлы, названия которых начинаются на префикс «АВ». В 1С:Предприятии 8 для этих целей предусмотрены мощные встроенные инструменты работы с файловой системой.
В этой статье мы подробно разберем, как правильно организовать поиск, какие существуют нюансы при работе на разных операционных системах и как сделать ваш код максимально производительным и надежным.
Самый простой и эффективный способ решить задачу — использовать встроенную функцию НайтиФайлы(). Она позволяет не просто перебирать всё содержимое папки, а сразу отфильтровать нужные объекты с помощью маски поиска. Рассмотрим, как это выглядит на практике.
Проанализируем пример кода, который решает задачу автора темы:
ПутьКПапке = "C:\MyFiles\";
МаскаПоиска = "АВ*"; // Ищем всё, что начинается на АВ
НайденныеФайлы = НайтиФайлы(ПутьКПапке, МаскаПоиска, Ложь);
Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
Сообщить("Найден файл: " + ТекущийФайл.Имя);
КонецЦикла;
Разберем параметры функции НайтиФайлы() по шагам:
* (звездочка) означает любое количество произвольных символов. Маска "АВ*" найдет и «АВ_отчет.xlsx», и «АВ123.txt», и просто «АВ».Истина, система будет искать файлы не только в указанной папке, но и во всех вложенных подпапках. В нашем случае мы передаем Ложь, так как ищем строго в конкретном каталоге.В ходе обсуждения на форуме возник важный вопрос: а что если в папке окажется подкаталог, чье имя тоже начинается на «АВ»? Например, папка с названием «АВ_Архив». Функция НайтиФайлы() вернет и файлы, и каталоги, подходящие под маску.
Выясним, как гарантированно отличить файл от папки. Для этого у объекта типа Файл, который возвращается в цикле, есть специальные методы. Использование проверки на наличие расширения (точки в имени) — ненадежно, так как папки тоже могут иметь точки в названиях, а файлы могут быть без расширений.
Рассмотрим правильный алгоритм проверки:
Для Каждого ОбъектПоиска Из НайденныеФайлы Цикл
Если ОбъектПоиска.ЭтоФайл() Тогда
// Это точно файл, выполняем действия
ОбработатьФайл(ОбъектПоиска.ПолноеИмя);
ИначеЕсли ОбъектПоиска.ЭтоКаталог() Тогда
// Это папка, ее мы пропускаем
Продолжить;
КонецЕсли;
КонецЦикла;
Использование методов ЭтоФайл() и ЭтоКаталог() делает ваш код устойчивым к особенностям именования объектов в файловой системе.
Посмотрим на ситуацию, когда нам нужно более точное соответствие. В 1С поддерживаются два основных спецсимвола в масках:
* — заменяет любую последовательность символов (включая пустую).? — заменяет ровно один произвольный символ.Если мы точно знаем, что после «АВ» должно идти ровно 3 цифры и расширение .txt, мы можем использовать маску "АВ???.txt". Это значительно ускорит работу системы, если в папке находятся тысячи файлов, так как фильтрация произойдет на уровне операционной системы, а не внутри цикла 1С.
Нужно учитывать, где именно выполняется код — на клиенте под Windows или на сервере под управлением Linux. Проанализируем ключевое различие: чувствительность к регистру.
В ОС Windows поиск по маске "АВ*" найдет и «ав_файл», и «АВ_ФАЙЛ». Однако в Linux регистр имеет значение. Если вы ищете файлы на Linux-сервере, маска "АВ*" не найдет файлы, начинающиеся со строчных букв «ав». В таких случаях рекомендуется либо приводить имена к одному регистру (если это возможно при создании файлов), либо выполнять поиск по всем файлам (маска "*") и проверять условие внутри цикла с помощью функции НРег().
// Универсальный способ для Linux (чувствителен к производительности)
ВсеФайлы = НайтиФайлы(Путь, "*", Ложь);
Для Каждого Файл Из ВсеФайлы Цикл
Если Лев(ВРег(Файл.Имя), 2) = "АВ" Тогда
// Файл найден независимо от регистра
КонецЕсли;
КонецЦикла;
Если вы разрабатываете решение для тонкого или веб-клиента (особенно для версий платформы 8.3.18 и выше), использование синхронного метода НайтиФайлы() может привести к «зависанию» интерфейса. Рассмотрим асинхронный аналог — НайтиФайлыАсинх().
Этот метод работает через механизм «Обещаний» (Promises). Он позволяет программе продолжать работу, пока диск или сеть отвечают на запрос. Это особенно критично при работе с сетевыми папками или медленными носителями.
При работе с внешними ресурсами всегда существует риск возникновения ошибок. Самые частые причины: отсутствие прав доступа к папке или физическое отсутствие пути. Хорошей практикой считается использование конструкции Попытка ... Исключение.
Попытка
НайденныеФайлы = НайтиФайлы(ПутьКПапке, "АВ*");
Исключение
ЗаписьЖурналаРегистрации("Поиск файлов", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка доступа к пути: " + ОписаниеОшибки());
Возврат; // Или другая обработка ошибки
КонецПопытки;
Также перед поиском можно проверить существование самого каталога, используя объект Файл:
ПроверкаКаталога = Новый Файл(ПутьКПапке);
Если Не ПроверкаКаталога.Существует() Тогда
Сообщить("Указанный путь не найден!");
КонецЕсли;
Для поиска файлов по префиксу в 1С наиболее правильно использовать функцию НайтиФайлы() с корректно настроенной маской. Это избавляет от необходимости перебирать лишние данные в цикле. Не забывайте использовать методы ЭтоФайл() для проверки типа объекта и учитывайте особенности операционной системы сервера, на которой исполняется ваш код.