Часто при разработке возникает необходимость получить наименования всех вложенных файлов и папок в определенном каталоге на диске. Давайте разберем эту задачу подробно и рассмотрим, какие инструменты предлагает нам встроенный язык 1С:Предприятие для работы с файловой системой (включая такие кейсы, как выгрузка картинок номенклатуры в каталог) — для этого есть обработка автоматического поиска и загрузки файлов в 1С. Мы проанализируем как базовые, так и современные подходы к решению проблемы.
Для начала рассмотрим самый простой вариант, когда нам нужно получить список элементов только в корне указанной папки, без углубления в подкаталоги. Для этой цели отлично подходит метод НайтиФайлы, который часто используют, реализуя поиск и удаление дублей файлов на компьютере. Разберем по шагам его синтаксис.
Метод принимает путь к каталогу и маску поиска. Посмотрим на пример кода:
МассивФайлов = НайтиФайлы(ПутьККаталогу, "*");
Для Каждого ТекущийФайл Из МассивФайлов Цикл
Сообщить(ТекущийФайл.ПолноеИмя);
КонецЦикла;
Важно обратить внимание на маску поиска. Многие по привычке используют маску *.*. Однако проанализируем ситуацию: маска *.* найдет только те файлы, в имени которых обязательно присутствует точка (то есть имеется расширение). Если в вашей папке лежат файлы без расширений или некоторые системные файлы, они будут пропущены. Поэтому универсальнее использовать маску *, которая гарантированно захватывает все элементы директории.
Если в нашей папке есть другие папки, и мы хотим заглянуть и в них, нам потребуется рекурсивный поиск. Разберем два пути решения этой задачи.
Путь 1: Собственная рекурсивная процедура
В этом случае мы перебираем элементы, и если натыкаемся на папку, снова вызываем нашу же процедуру. Посмотрим на пример:
Процедура ОбойтиКаталогРекурсивно(ПутьККаталогу)
ЭлементыКаталога = НайтиФайлы(ПутьККаталогу, "*");
Для Каждого Элемент Из ЭлементыКаталога Цикл
Если Элемент.ЭтоКаталог() Тогда
ОбойтиКаталогРекурсивно(Элемент.ПолноеИмя);
Иначе
Сообщить("Найден файл: " + Элемент.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры;
Путь 2: Встроенная возможность платформы
Платформа 1С позволяет сделать это намного проще. У метода НайтиФайлы есть третий параметр — признак поиска в подкаталогах. Если установить его в Истина, система сама соберет все вложенные элементы, значительно упрощая поиск дубликатов файлов во всей иерархии папок.
МассивВсехФайлов = НайтиФайлы(ПутьККаталогу, "*", Истина);
Функции поиска возвращают нам не просто строки с путями, а массив объектов типа Файл. Рассмотрим подробнее, как мы можем с ним взаимодействовать внутри цикла (например, если нам попался новый распаковщик конфигураций в архиве).
ЭтоКаталог() и ЭтоФайл() — позволяют разделить логику. Например, папки мы можем пропускать, а документы — обрабатывать.ПолноеИмя — отдает абсолютный путь (например, "C:\Temp\document.txt").Имя и ИмяБезРасширения — избавляют нас от необходимости писать функции работы со строками, чтобы отрезать расширение файла.При работе в современных версиях 1С (начиная с 8.3.18) на стороне клиента обычный вызов метода поиска может привести к блокировке интерфейса, особенно если файлов тысячи. Выясним причину: синхронный код заставляет программу ждать завершения операции жесткого диска. Чтобы интерфейс не "зависал", рассмотрим асинхронный аналог — НайтиФайлыАсинх.
&НаКлиенте
Асинх Процедура НайтиФайлыАсинхронно(Команда)
Путь = "C:\МоиДокументы";
МассивФайлов = Ждать НайтиФайлыАсинх(Путь, "*", Истина);
Для Каждого ТекущийФайл Из МассивФайлов Цикл
Если Не ТекущийФайл.ЭтоКаталог() Тогда
Сообщить(ТекущийФайл.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры;
В завершение проанализируем частые проблемы, связанные с контекстом выполнения кода.
Если вы выполняете код &НаСервере, поиск происходит в файловой системе самого сервера 1С. Главная проблема — права доступа. Пользователь операционной системы, под которым запущена служба сервера 1С, должен иметь права на чтение указанной папки. Если их нет, метод вернет пустой массив без выдачи ошибки.
Если же код выполняется в веб-клиенте (в браузере), прямой доступ к локальным дискам пользователя ограничен. Для корректной работы метода потребуется предварительно установить расширение для работы с файлами в веб-клиенте, иначе платформа выдаст предупреждение безопасности.