Как обойти ограничение на количество файлов при работе с FTP в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При активном обмене данными через FTP-серверы разработчики 1С часто сталкиваются с ситуацией, когда в одной директории скапливается огромное количество файлов (от 10 000 и выше). В определенный момент стандартные механизмы платформы, такие как метод НайтиФайлы объекта FTPСоединение, перестают возвращать полный список объектов или выдают ошибку. Рассмотрим подробнее, почему это происходит и какими способами можно решить данную проблему.

Выясним причину: почему 1С «не видит» больше 9999 файлов?

Распространенное заблуждение гласит, что это внутреннее ограничение платформы 1С. Однако на практике ситуация сложнее. Проанализируем основные факторы, влияющие на этот лимит:

  1. Настройки FTP-сервера: Большинство популярных серверов (например, ProFTPD или Pure-FTPd), используемых на хостингах, имеют параметр ListOptions или аналогичные настройки лимитов. Для обеспечения стабильности системы хостеры ограничивают количество объектов, возвращаемых по команде LIST, числом 10 000 или даже меньше.
  2. Таймауты соединения: Формирование текстового списка из 20 000–30 000 файлов — ресурсоемкая операция для файловой системы сервера. Если сервер не успевает отдать список за отведенное время, 1С разрывает соединение или возвращает пустой массив.
  3. Производительность файловой системы: В операционных системах Linux (ext3/ext4) хранение огромного количества файлов в одном корневом каталоге приводит к существенному замедлению операций поиска и удаления из-за особенностей индексации.

Решение 1: Удаление «вслепую» по прямой ссылке

Если ваша задача заключается в удалении файлов, имена которых уже известны в базе данных 1С (например, они хранятся в регистре сведений или справочнике), вам вообще не нужно использовать метод НайтиФайлы. Рассмотрим, как это работает: метод Удалить объекта FTPСоединение работает по прямому пути к файлу. Серверу не нужно сканировать всю папку, чтобы выполнить эту команду.

Проанализируем пример кода для прямого удаления:


// Предположим, СписокФайловНаУдаление - это массив имен файлов из базы 1С
FTP = Новый FTPСоединение(Сервер, Порт, Логин, Пароль, , Истина); // Пассивный режим
Для Каждого ИмяФайла Из СписокФайловНаУдаление Цикл
    Попытка
        ПолныйПуть = "/exchange/orders/" + ИмяФайла;
        FTP.Удалить(ПолныйПуть);
    Исключение
        ЗаписьЖурналаРегистрации("FTP_Ошибка", УровеньЖурналаРегистрации.Предупреждение, , , 
            "Не удалось удалить файл: " + ИмяФайла + ". Ошибка: " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

Важный момент: Этот способ полностью обходит лимит листинга (отображения), так как команда на удаление отправляется точечно.

Решение 2: Использование масок для обхода лимита листинга

Если же вам необходимо именно получить список файлов, чтобы понять, что накопилось на сервере, а общее количество превышает лимит хостинга, мы можем применить метод «разделяй и властвуй». Разберем по шагам: вместо запроса всех файлов *.*, мы будем запрашивать их порциями, используя маски имен.

Посмотрим на пример реализации перебора по алфавиту:


Функция ПолучитьВсеФайлыЧерезМаски(FTPСоединение, ПутьКПапке)
    МассивРезультатов = Новый Массив;
    СимволыДляМаски = "0123456789abcdefghijklmnopqrstuvwxyz";
    
    Для Итератор = 1 По СтрДлина(СимволыДляМаски) Цикл
        ТекущийСимвол = Сред(СимволыДляМаски, Итератор, 1);
        Маска = ТекущийСимвол + "*.*";
        
        НайденныеФайлы = FTPСоединение.НайтиФайлы(ПутьКПапке, Маска);
        Для Каждого Файл Из НайденныеФайлы Цикл
            МассивРезультатов.Добавить(Файл);
        КонецЦикла;
    КонецЦикла;
    
    Возвращает МассивРезультатов;
КонецФункции

Этот алгоритм заставляет сервер каждый раз отдавать только малую часть списка, которая гарантированно впишется в настройки ListOptions хостинга.

Решение 3: Архитектурное изменение структуры хранения

Как отмечали участники обсуждения, «благородная идея запнулась», но именно разбиение файлов по подпапкам является промышленным стандартом. Если у вас есть возможность изменить логику выгрузки файлов на FTP, обязательно внедрите иерархическую структуру.

Рассмотрим варианты организации структуры:

В 1С создание директории выполняется методом FTPСоединение.СоздатьКаталог(). Проанализируем ситуацию: даже если файлов будет миллион, в каждой конкретной папке их будет всего несколько сотен, что обеспечит мгновенную работу НайтиФайлы.

Решение 4: Внешние компоненты и системные утилиты

Если штатное FTPСоединение не справляется или работает слишком медленно, проанализируем использование внешних инструментов. Одним из самых надежных вариантов является библиотека WinSCP.

Преимущества использования WinSCP через COM-объект:

  1. Поддержка протоколов SFTP и FTPS.
  2. Автоматическая обработка разрывов соединений.
  3. Возможность синхронизации целых директорий одной командой.
  4. Отсутствие жестких ограничений на количество файлов при правильной настройке.

Также можно рассмотреть использование консольной утилиты curl. Мы можем сформировать текстовый файл со списком команд и выполнить его одной командой ОС через ЗапуститьПриложение(), что будет значительно быстрее, чем построчный перебор в цикле 1С.

Подведем итоги

Мы выяснили, что проблема «9999 файлов» чаще всего кроется в настройках сервера, а не в 1С. Для решения проблемы мы рекомендуем:

← На главную