Разработка и Конфигурация · 12 мин
Как прочитать файлы из каталога в 1С
Как прочитать файлы из каталога в 1С: методы НайтиФайлы и НайтиФайлыАсинх, фильтры по маске, обход подкаталогов, проверка результатов и типичные ошибки.
Задача прочитать файлы из каталога возникает в 1С постоянно: загрузка выписок из папки обмена с банком, импорт прайсов поставщиков, обработка сканов документов, интеграция с внешними системами через файловый обмен. Во всех этих сценариях используется один и тот же инструмент — методы НайтиФайлы (синхронный) и НайтиФайлыАсинх (асинхронный), которые возвращают массив объектов типа «Файл».
Важно понимать ключевое ограничение: код, работающий с файловой системой, выполняется там, где он запущен. Если процедура выполняется на сервере, каталог ищется на дисках сервера 1С, а не на компьютере пользователя. Это самая частая причина ситуации «на моём компьютере работает, а в проде — нет».
Ниже разобраны оба метода, фильтрация по маске, рекурсивный обход подкаталогов, чтение содержимого найденных файлов, проверка результатов и типичные ошибки с готовыми примерами кода на встроенном языке.
Метод НайтиФайлы: базовый синтаксис
Метод НайтиФайлы доступен и на клиенте, и на сервере. Он принимает три параметра: путь к каталогу, маска поиска и признак поиска в подкаталогах. Минимальный вариант — один параметр, путь к папке:
НайденныеФайлы = НайтиФайлы("D:\Обмен\Выписки");
Для Каждого Файл Из НайденныеФайлы Цикл
Сообщить(Файл.ПолноеИмя);
КонецЦикла;
Если каталог не существует, метод не вызывает исключение — он просто возвращает пустой массив. Поэтому проверку существования папки нужно делать отдельно, иначе вы не отличите «папки нет» от «папка пустая»:
Каталог = Новый Файл("D:\Обмен\Выписки");
Если Не Каталог.Существует() Тогда
ВызватьИсключение "Каталог обмена не найден: D:\Обмен\Выписки";
КонецЕсли;
Каждый элемент массива — объект типа «Файл» с полезными свойствами: ПолноеИмя, Имя, ИмяБезРасширения, Расширение, Путь, Размер(), ПолучитьВремяИзменения(), а также методы ЭтоКаталог() и ЭтоФайл(). Этого достаточно, чтобы отфильтровать нужное уже после поиска.
Фильтрация по маске и расширению
Второй параметр — маска имени файла. Поддерживаются стандартные подстановочные символы: * — любая последовательность символов, ? — один произвольный символ. Чтобы получить только XML-файлы выписок:
НайденныеФайлы = НайтиФайлы("D:\Обмен\Выписки", "*.xml");
Маска сравнивается без учёта регистра на Windows, но на Linux регистр может иметь значение — это зависит от файловой системы. Если обмен идёт через Linux-сервер, надёжнее искать по широкой маске и проверять расширение в коде:
Для Каждого Файл Из НайденныеФайлы Цикл
Если НРег(Файл.Расширение) <> ".xml" Тогда
Продолжить;
КонецЕсли;
// обработка файла
КонецЦикла;
Несколько масок в одном вызове передать нельзя. Если нужно забрать, например, и XML, и CSV, либо вызывайте НайтиФайлы дважды и объединяйте массивы, либо ищите по маске . и фильтруйте в цикле. Второй вариант обычно быстрее при большом числе файлов, потому что каталог читается один раз.
Обход подкаталогов и сортировка по дате
Третий параметр — булево «искать в подкаталогах». Со значением Истина метод рекурсивно обходит всё дерево папок:
НайденныеФайлы = НайтиФайлы("D:\Архив", "*.pdf", Истина);
Рекурсивный поиск по большому дереву (сотни тысяч файлов, сетевой диск) может занимать заметное время и блокировать сеанс. Если структура папок известна — например, «Год\Месяц\файлы» — эффективнее обходить каталоги явно, контролируя глубину и обрабатывая файлы порциями.
Типовая задача — взять только самый свежий файл (последняя выгрузка из банка). Для этого массив перебирается с сравнением времени изменения:
ПоследнийФайл = Неопределено;
Для Каждого Файл Из НайденныеФайлы Цикл
Если Не Файл.ЭтоФайл() Тогда
Продолжить;
КонецЕсли;
Если ПоследнийФайл = Неопределено
Или Файл.ПолучитьВремяИзменения() > ПоследнийФайл.ПолучитьВремяИзменения() Тогда
ПоследнийФайл = Файл;
КонецЕсли;
КонецЦикла;
- 1Проверьте существование каталога через объект Файл и метод Существует()
- 2Вызовите НайтиФайлы с путём, маской и признаком поиска в подкаталогах
- 3Отфильтруйте результат: ЭтоФайл(), расширение, дата изменения
- 4Прочитайте содержимое каждого файла подходящим читателем (ЧтениеТекста, ЧтениеXML, ЧтениеДанных)
- 5После успешной загрузки переместите файл в архивную папку, чтобы не обработать его повторно
Чтение содержимого найденных файлов
НайтиФайлы возвращает только описания файлов, а не их содержимое. Дальше файл открывается подходящим объектом в зависимости от формата. Для текстовых файлов используется ЧтениеТекста:
Чтение = Новый ЧтениеТекста(Файл.ПолноеИмя, КодировкаТекста.UTF8);
Текст = Чтение.Прочитать();
Чтение.Закрыть();
Для XML — ЧтениеXML с последовательным перебором узлов, для двоичных данных (картинки, PDF) — ЧтениеДанных или помещение файла во временное хранилище через НачатьПомещениеФайла на клиенте. Кодировку текстового файла нужно знать заранее: банковские выписки нередко приходят в ANSI (windows-1251), и чтение их как UTF-8 даст нечитаемые символы.
Если файл должен попасть с клиента на сервер (например, пользователь выбрал папку у себя), простого чтения недостаточно — сервер не видит клиентский диск. Используйте НачатьПомещениеФайлов или передавайте файлы через временное хранилище, а на сервере уже обрабатывайте двоичные данные.
Файлы = НайтиФайлы(ПутьККаталогу, "*.xml", Ложь);
Для Каждого Файл Из Файлы Цикл
Если Файл.ЭтоФайл() Тогда
Чтение = Новый ЧтениеТекста(Файл.ПолноеИмя, КодировкаТекста.UTF8);
Содержимое = Чтение.Прочитать();
Чтение.Закрыть();
КонецЕсли;
КонецЦикла;Асинхронный вариант: НайтиФайлыАсинх
В тонком и веб-клиенте синхронные вызовы файловой системы либо запрещены режимом использования модальности, либо требуют расширения работы с файлами. Современный подход — асинхронный метод НайтиФайлыАсинх с описанием оповещения:
Оповещение = Новый ОписаниеОповещения("ПослеПоискаФайлов", ЭтотОбъект);
НачатьНайтиФайлы(Оповещение, "D:\Обмен", "*.xml", Истина);
Результат приходит в процедуру, указанную в оповещении, где первым параметром передаётся тот же массив объектов «Файл». Логика обработки внутри не отличается от синхронного варианта — меняется только способ получения массива.
Асинхронные методы требуют, чтобы у пользователя было установлено расширение работы с файлами (в веб-клиенте) или разрешён доступ к файловой системе. Если расширение не установлено, платформа предложит установить его — предусмотрите эту ветку в обработке, иначе пользователь увидит немую ошибку.
Клиент или сервер: где выполнять поиск
Выбор места выполнения определяет, чей диск будет прочитан. Серверный вызов видит только диски и сетевые пути, доступные учётной записи, под которой работает агент сервера 1С (обычно это служебная учётная запись, а не пользователь). Клиентский вызов видит диски конкретного пользователя.
Для регламентных заданий (автоматический разбор папки обмена по расписанию) подходит только сервер: регламентные задания выполняются на сервере и не имеют клиентского контекста. Путь к папке обмена при этом должен быть сетевым (вида \\server\share) и доступным учётной записи агента — локальный путь D:\Обмен будет указывать на диск самого сервера.
Сравнение вариантов
Подходит для регламентных заданий и фоновой обработки. Ограничение: видит только диски сервера и сетевые пути, доступные учётной записи агента 1С.
Подходит для интерактивной работы с локальными папками пользователя. Ограничение: не работает в тонком и веб-клиенте без расширения.
Единственный корректный вариант для тонкого и веб-клиента. Требует расширения работы с файлами и перестройки кода на оповещения.
Подходит, когда папка находится на удалённом ресурсе. Ограничение: нужен отдельный код обмена, НайтиФайлы здесь не применяется.
Типичные ошибки и ограничения
Первая и самая массовая ошибка — поиск на сервере по пути, который существует только на клиенте. Код «работает у разработчика» в файловой базе (где клиент и сервер — один компьютер) и перестаёт работать в клиент-серверном варианте. Проверяйте, где физически находится каталог.
Вторая ошибка — отсутствие прав. Учётная запись агента сервера 1С должна иметь чтение (а для перемещения обработанных файлов — и запись) в целевой папке. Ошибка прав проявляется как пустой результат или исключение при чтении файла, и диагностируется запуском поиска под той же учётной записью.
Третья группа проблем — обработка неполностью записанных файлов. Если внешняя система кладёт файл в папку, а 1С его тут же подхватывает, можно прочитать обрезанный файл. Надёжные приёмы: дожидаться, пока размер файла перестанет меняться, либо принимать файлы с временным расширением (.tmp), которое отправитель переименовывает после полной записи.
Проверка результата и FAQ
После внедрения обработки проверьте три вещи: массив не пустой (иначе молча ничего не загрузится), каждый обработанный файл убран из исходной папки или записан в регистр обработанных, а в журнале регистрации есть запись о результате каждой итерации. Без журналирования разбор сбоев файлового обмена превращается в гадание.
Как проверить результат
Содержит ожидаемое число объектов Файл
Пустой массив при заведомо непустой папке — проверяйте путь, маску и место выполнения кода
Текст читается, кириллица отображается корректно
Кракозябры — неверная кодировка; обрезанные данные — файл был недописан
Уже загруженные файлы пропускаются
Данные задваиваются — нет архивирования или учёта обработанных файлов
Как получить только файлы, без подкаталогов?
Отфильтруйте массив после НайтиФайлы: в цикле проверяйте Файл.ЭтоФайл() и пропускайте элементы, для которых оно возвращает Ложь. Отдельного параметра «только файлы» у метода нет.
Почему НайтиФайлы возвращает пустой массив, хотя файлы в папке есть?
Чаще всего код выполняется на сервере, а папка находится на компьютере пользователя. Также проверьте маску (на Linux учитывается регистр), права учётной записи и то, что путь указан без опечаток и завершающего слэша не мешает поиску.
Как прочитать файлы из сетевой папки?
Укажите UNC-путь вида \\сервер\ресурс\папка. Для серверного выполнения сетевой ресурс должен быть доступен учётной записи агента сервера 1С — подключённый сетевой диск пользователя сервер не увидит.
Можно ли искать по нескольким расширениям сразу?
Одним вызовом — нет, маска одна. Либо вызывайте НайтиФайлы несколько раз и объединяйте массивы, либо ищите по маске . и проверяйте расширение в цикле. Второй способ быстрее на больших каталогах.
Как обработать только новые файлы, не трогая старые?
Сравнивайте время изменения файла с датой последнего запуска, которую храните в константе или регистре, либо перемещайте обработанные файлы в архивный подкаталог. Второй способ надёжнее, так как не зависит от корректности дат.
Работает ли НайтиФайлы в веб-клиенте?
Синхронный вызов — нет. Используйте НачатьНайтиФайлы с описанием оповещения и установленным расширением работы с файлами в браузере. Без расширения доступ к локальной файловой системе из веб-клиента невозможен.
Что важно запомнить
Файлы из каталога читаются методом НайтиФайлы с путём, маской и признаком обхода подкаталогов; результат — массив объектов «Файл», который нужно фильтвать через ЭтоФайл() и расширение. Код на сервере видит только диски сервера, для тонкого и веб-клиента используйте асинхронный НачатьНайтиФайлы. После загрузки перемещайте файлы в архив и журналируйте результат — это защищает от дублей и упрощает диагностику.