В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача автоматизации обработки внешних данных. Это может быть загрузка прайс-листов, чтение логов или импорт заказов из сторонних систем. Ключевым этапом здесь является получение списка файлов, находящихся в определенной директории. В этой статье мы подробно разберем, как правильно реализовать этот механизм, учитывая контекст исполнения кода и особенности различных операционных систем.
Основным инструментом для решения нашей задачи является встроенная функция НайтиФайлы. Проанализируем её синтаксис и параметры. Функция предназначена для поиска файлов и каталогов, соответствующих заданному шаблону. Важно понимать, что при выполнении кода на сервере, путь к каталогу должен быть доступен именно серверному процессу 1cv8, а не текущему пользователю компьютера.
Рассмотрим простейший пример, когда нам нужно получить список всех файлов в папке без учета вложенных каталогов. Разберем код по шагам:
// Определим путь к каталогу на сервере
ПутьККаталогу = "C:\Exchange\Import\";
// Зададим маску поиска (все файлы)
Маска = "*.*";
// Получаем массив объектов типа Файл
НайденныеФайлы = НайтиФайлы(ПутьККаталогу, Маска);
Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
Если ТекущийФайл.ЭтоФайл() Тогда
Сообщить("Найден файл: " + ТекущийФайл.Имя);
КонецЕсли;
КонецЦикла;
В данном примере функция НайтиФайлы возвращает массив объектов типа Файл. Каждый такой объект содержит полную информацию о найденном элементе: его имя, расширение, размер, дату изменения и тип (файл или каталог).
Зачастую структура хранения данных подразумевает наличие подкаталогов (например, разбивка по датам или контрагентам). Чтобы не писать сложные циклы обхода дерева папок вручную, проанализируем третий параметр функции НайтиФайлы — ИскатьВПодкаталогах.
Если установить этот параметр в значение Истина, платформа самостоятельно выполнит рекурсивный обход всей структуры каталогов, начиная с указанного пути. Посмотрим на практический пример поиска всех текстовых документов в иерархии папок:
ПутьККаталогу = "/home/1c/exchange/data/"; // Пример пути для Linux
Маска = "*.txt";
// Включаем рекурсивный поиск
СписокФайлов = НайтиФайлы(ПутьККаталогу, Маска, Истина);
Для Каждого Файл Из СписокФайлов Цикл
// Выведем полное имя с путем, чтобы понимать, в какой подпапке найден файл
Сообщить("Обнаружен файл: " + Файл.ПолноеИмя);
КонецЦикла;
Выясним причину, по которой использование этого метода предпочтительнее ручного обхода: встроенные алгоритмы платформы оптимизированы для работы с файловой системой и работают значительно быстрее, чем рекурсивные вызовы в коде 1С, особенно при большом количестве вложенных уровней.
Просто получить список имен часто бывает недостаточно. Разберем ситуацию, когда нам нужно отобрать только те файлы, которые были изменены за последние сутки и имеют размер более 1 мегабайта. Для этого мы будем использовать свойства объекта Файл.
Проанализируем основные свойства, которые нам понадобятся:
Размер() — возвращает размер файла в байтах.ПолучитьВремяИзменения() — возвращает дату и время последнего сохранения файла.ИмяБезРасширения — удобно для логирования или сопоставления с объектами в базе.Расширение — позволяет дополнительно фильтровать данные в коде.Применим эти знания в комплексном примере:
ТекущаяДата = ТекущаяДатаСеанса();
СуткиВСекундах = 24 * 60 * 60;
МинимальныйРазмер = 1024 * 1024; // 1 Мб
НайденныеЭлементы = НайтиФайлы("C:\Logs\", "*.log");
Для Каждого Элемент Из НайденныеЭлементы Цикл
Если Элемент.ЭтоФайл() Тогда
ВремяИзменения = Элемент.ПолучитьВремяИзменения();
РазмерФайла = Элемент.Размер();
Если (ТекущаяДата - ВремяИзменения < СуткиВСекундах) И (РазмерФайла > МинимальныйРазмер) Тогда
// Файл подходит под наши условия
ОбработатьЛогФайл(Элемент.ПолноеИмя);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Рассмотрим подробнее критически важный аспект: права доступа. Когда код выполняется на стороне сервера (в модуле менеджера, в общем модуле с галкой "Сервер" или в фоновом задании), он работает от имени пользователя операционной системы, под которым запущен процесс rphost (в Windows это часто USR1CV8 или LocalSystem).
Если вы пытаетесь получить доступ к сетевой папке (например, \\ServerName\Share\), убедитесь в следующем:
/Data/ и /data/ — это разные директории).Проанализируем типичную ошибку: если функция НайтиФайлы возвращает пустой массив, хотя файлы в папке точно есть, в 99% случаев это связано именно с отсутствием прав доступа у серверной учетной записи 1С к указанному ресурсу.
После того как мы нашли нужные файлы и успешно их прочитали, хорошим тоном считается их перемещение в архив или удаление, чтобы избежать повторной обработки. Разберем, как это сделать безопасно, используя методы ПереместитьФайл и УдалитьФайлы.
КаталогАрхива = "C:\Exchange\Archive\";
// Проверим наличие папки архива, если её нет — создадим
Если НайтиФайлы(КаталогАрхива).Количество() = 0 Тогда
СоздатьКаталог(КаталогАрхива);
КонецЕсли;
Для Каждого ОбработанныйФайл Из МассивОбработанныхФайлов Цикл
Попытка
НовыйПуть = КаталогАрхива + ОбработанныйФайл.Имя;
ПереместитьФайл(ОбработанныйФайл.ПолноеИмя, НовыйПуть);
Сообщить("Файл успешно перенесен в архив: " + ОбработанныйФайл.Имя);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось переместить файл: " + ОбработанныйФайл.Имя + ". Ошибка: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
Обратите внимание на использование блока Попытка...Исключение. При работе с файловой системой это обязательно, так как файл может быть заблокирован другой программой или антивирусом в момент попытки перемещения.
Мы проанализировали основные методики работы с файловой системой на сервере 1С. Подведем итоги: для эффективного поиска используйте НайтиФайлы с грамотно настроенными масками и параметром рекурсии. Всегда проверяйте контекст исполнения (Клиент/Сервер) и наличие прав у пользователя ОС, под которым работает сервер приложений. Следуя этим рекомендациям, вы сможете создавать надежные и быстрые механизмы обмена данными.