В процессе разработки в среде 1С часто возникает необходимость автоматизировать обработку файлов: будь то загрузка прайс-листов из определенной папки, обработка выгрузок из сторонних систем или архивация логов. Для таких задач часто применяется выгрузка внешних отчетов и обработок во внешние каталоги для их последующего анализа. В данной статье мы проанализируем основные способы получения списка файлов, разберем особенности работы на клиенте и сервере, а также рассмотрим примеры реализации рекурсивного поиска.
Основным инструментом для решения нашей задачи является функция НайтиФайлы(). Она универсальна и позволяет получить массив объектов типа Файл, которые соответствуют заданным критериям. Иногда после поиска требуется более глубокая работа с содержимым, например, если используется специализированный распаковщик конфигураций для анализа файлов cf или epf. Давайте посмотрим на синтаксис этой функции:
// Синтаксис:
// НайтиФайлы(<Путь>, <Маска>, <ИскатьВПодкаталогах>)
Где:
Разберем по шагам простейший пример получения всех файлов в конкретной папке на сервере:
Процедура ПолучитьСписокФайловНаСервере(ПутьККаталогу)
// Получаем массив объектов типа "Файл"
НайденныеФайлы = НайтиФайлы(ПутьККаталогу, "*.*", Ложь);
// Проанализируем полученный результат
Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
Если ТекущийФайл.ЭтоФайл() Тогда
Сообщить("Найден файл: " + ТекущийФайл.Имя + ", Размер: " + ТекущийФайл.Размер());
ИначеЕсли ТекущийФайл.ЭтоКаталог() Тогда
Сообщить("Найдена папка: " + ТекущийФайл.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Когда мы получаем результат работы функции НайтиФайлы(), мы работаем с массивом объектов Файл. Выясним, какие наиболее полезные свойства и методы предоставляет этот объект:
Имя — краткое имя файла с расширением.ПолноеИмя — абсолютный путь к файлу в файловой системе.Расширение — расширение файла (включая точку).Размер() — метод, возвращающий размер файла в байтах.ПолучитьВремяИзменения() — возвращает дату и время последнего сохранения файла.ЭтоФайл() и ЭтоКаталог() — логические методы для определения типа объекта.Иногда стандартного параметра функции НайтиФайлы для поиска в подкаталогах недостаточно, или нам требуется сложная логика обработки структуры папок. В таких случаях мы можем реализовать собственный рекурсивный обход. Рассмотрим подробнее, как это выглядит в коде:
Процедура ОбходКаталогаРекурсивно(ТекущийПуть)
СписокОбъектов = НайтиФайлы(ТекущийПуть, "*.*");
Для Каждого Объект Из СписокОбъектов Цикл
Если Объект.ЭтоКаталог() Тогда
// Если это папка, вызываем эту же процедуру для вложенного пути
Сообщить("Заходим в директорию: " + Объект.ПолноеИмя);
ОбходКаталогаРекурсивно(Общий.ПолноеИмя);
Иначе
// Если это файл, выполняем полезное действие
ОбработатьФайл(Объект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОбработатьФайл(ФайлОбъект)
Сообщить("Обработка файла: " + ФайлОбъект.ПолноеИмя);
КонецПроцедуры
Проанализируем ситуацию: рекурсия удобна тем, что мы можем фильтровать папки по именам или ограничивать глубину вложения, что невозможно сделать стандартным параметром функции.
При работе в управляемом приложении (v8.3) крайне важно понимать, где выполняется код. Если ваша задача включает копирование файлов и каталогов между Клиентом и Сервером, выясним причину возможных ошибок доступа:
Для обеспечения стабильной работы рекомендуем всегда проверять наличие прав доступа к каталогу перед началом поиска с помощью метода ВводДоступен() или просто используя блок Попытка...Исключение.
Если ваша конфигурация используется в браузере, использование синхронных вызовов (таких как просто НайтиФайлы) может быть запрещено или приводить к "зависанию" интерфейса. В современных версиях платформы 1С:Предприятие 8.3 для работы на клиенте рассмотрим использование асинхронных методов поиска файлов.
&НаКлиенте
Асинхронная Процедура НайтиФайлыАсинхронно()
ПараметрыПоиска = Новый ПараметрыПоискаФайлов(Истина); // Включая подкаталоги
Найденные = Ждать НайтиФайлыАсинхронно("C:\MyFiles", "*.pdf", ПараметрыПоиска);
Для Каждого Файл Из Найденные Цикл
Сообщить(Файл.Имя);
КонецЦикла;
КонецПроцедуры
Разберем по шагам: использование ключевого слова Ждать (Await) позволяет коду выглядеть линейно, при этом не блокируя поток исполнения интерфейса. Это особенно актуально для облачных решений.
Маска файла — это мощный инструмент. Посмотрим на примеры эффективного использования масок:
"*.txt" — только текстовые файлы."отчет_2023_??_??.xlsx" — файлы Excel. Часто это следующий шаг после того, как выполнена конвертация файлов из CSV в XLS в автоматическом режиме."*.*" — все файлы без исключения.Важный момент: если вам нужно найти файлы по нескольким разным маскам, проанализируем два пути: либо вызывать функцию несколько раз, либо получить все файлы "*.*" и фильтровать их программно, проверяя свойство Расширение.
// Пример программной фильтрации нескольких расширений
МассивРасширений = Новый Массив;
МассивРасширений.Добавить(".jpg");
МассивРасширений.Добавить(".png");
НайденныеФайлы = НайтиФайлы(ПутьККаталогу, "*.*");
Для Каждого Файл Из НайденныеФайлы Цикл
Если МассивРасширений.Найти(НРег(Файл.Расширение)) <> Неопределено Тогда
// Это нужное нам изображение
КонецЕсли;
КонецЦикла;
Если в вашей конфигурации используется БСП, рассмотрим возможности общего модуля ФайловаяСистема.
Использование БСП позволяет избежать написания платформозависимого кода и делает решение более универсальным. Например, функции БСП часто включают встроенные проверки на корректность путей и обработку ошибок прав доступа.
Подводя итог, сформулируем основные правила эффективной работы со списками файлов в 1С:
НайтиФайлы с третьим параметром Истина для простого поиска во вложенных папках.Разобрав эти инструменты, вы сможете гибко управлять файловыми потоками в своих разработках, обеспечивая высокую надежность и производительность системы.