Почему медленно удаляются файлы с FTP в 1С и как это ускорить

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

При работе с внешними хранилищами данных через протокол FTP программисты 1С часто сталкиваются с проблемой критического снижения скорости операций. Ситуация, когда в одной папке на сервере скапливается «дохринилион» файлов (от 50 000 до 100 000 и более), приводит к тому, что стандартная команда FTPСоединение.Удалить() начинает выполняться по несколько минут. В этой статье мы подробно разберем, как именно 1С взаимодействует с сервером, почему возникают задержки и как оптимизировать процесс удаления.

Как 1С выполняет команду удаления на самом деле

Рассмотрим стандартный программный код, который обычно используется для очистки папки на FTP-сервере:


Для каждого СтрФ Из ВсеФайлы Цикл
    НовоеИмяФ = СтрФ.ИмяФайла;
    Попытка
        FTP.Удалить(СокрЛП(FTP_ПапкаДляФайлов), НовоеИмяФ);
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

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

Важный технический нюанс: при вызове метода 1С может инициировать команды LIST или NLST для получения списка файлов в указанной директории. Если в папке находится 100 000 файлов, серверу требуется значительное время, чтобы сформировать этот список (текстовый поток объемом в несколько мегабайт) и передать его клиенту. Пока этот «листинг» не будет полностью прочитан 1С, реальная команда на удаление файла не будет отправлена. Именно это ожидание пользователь воспринимает как «зависание» на 4-5 минут.

Проблема «плоских» директорий на стороне сервера

Выясним причину, почему даже прямая команда удаления может работать медленно. Проблема кроется в архитектуре файловых систем (NTFS, ext4 и другие). Когда папка содержит огромное количество объектов, поиск конкретной записи в таблице дескрипторов файлов становится трудоемкой операцией для операционной системы сервера.

  1. Индексация: Поиск файла myfile.jpg среди 100 000 позиций в одной таблице требует перебора или сложного поиска по индексам, которые могут быть фрагментированы.
  2. Лимиты сервера: FTP-серверы (например, vsftpd или IIS) часто имеют внутренние ограничения на количество файлов в одной выдаче. Если лимит превышен, 1С может вообще не «увидеть» файл, который нужно удалить, или потратить ресурсы на бесконечные попытки синхронизации списка.

Решение №1: Реструктуризация системы хранения (Разбиение по папкам)

Самый правильный и надежный способ — не хранить все файлы в одной «куче». Проанализируем оптимальную структуру хранения. Вместо того чтобы складывать 500 000 картинок в корень /images/, следует распределять их по подпапкам на основе их идентификаторов или даты загрузки.

Рекомендуемый алгоритм:

При такой структуре команда FTP.Удалить() будет отрабатывать практически мгновенно (за 0.1 – 0.5 секунды), так как 1С и серверу придется оперировать списком из нескольких десятков файлов вместо сотен тысяч.

Решение №2: Использование внешних утилит (cURL или WinSCP)

Если изменить структуру папок на сервере невозможно (например, это сторонний ресурс), разберем способ обхода штатных механизмов 1С. Мы можем отправить прямую команду протокола без предварительного получения списка файлов. Для этого отлично подходят консольные утилиты, такие как curl.

Пример вызова прямой команды удаления через 1С:


КомандаСистемы = "curl -u user:password -X ""DELE /path/to/file/filename.ext"" ftp://myserver.com";
ЗапуститьПриложение(КомандаСистемы, , Истина);

В данном случае утилита curl посылает серверу только команду DELE. Сервер сразу приступает к удалению, минуя стадию LIST. Это сокращает время операции с минут до долей секунды.

Решение №3: Использование .NET и FtpWebRequest (для Windows-серверов)

Для более «чистой» реализации внутри 1С без вызова внешних окон можно использовать возможности .NET через COM-объекты. Рассмотрим пример использования класса FtpWebRequest, который позволяет гибко управлять командами FTP.


// Пример логики на языке 1С через использование объектов Windows
// Данный подход позволяет избежать 'листинга' каталога
МетодУдаления = "DELETE";
Запрос = Враппер.Create("System.Net.FtpWebRequest", "ftp://server.com/file.txt");
Запрос.Method = "DELE";
Запрос.Credentials = Враппер.Create("System.Net.NetworkCredential", "user", "pass");
Ответ = Запрос.GetResponse();

Этот метод работает по принципу «выстрелил и забыл», не требуя от платформы 1С предварительного анализа содержимого папки.

Итоги и рекомендации

Подведем итоги нашего анализа. Медленная работа FTPСоединение в 1С при больших объемах данных — это не ошибка платформы, а следствие универсальности её методов, которые пытаются обеспечить надежность за счет избыточных проверок (получения списка файлов).

Для стабильной работы системы придерживайтесь следующих правил:

  1. Всегда старайтесь ограничивать количество файлов в одной папке на FTP (не более 5 000 – 10 000 объектов).
  2. Если файлов много, используйте иерархическую структуру папок.
  3. Для массового удаления файлов в «плоских» папках откажитесь от штатного метода FTP.Удалить() в пользу внешних вызовов через curl или специализированные программы синхронизации (например, Allway Sync), которые умеют работать с FTP-потоками гораздо эффективнее встроенных средств 1С.
  4. При использовании штатного метода всегда проверяйте настройки таймаутов (Таймаут в FTPСоединение), так как при 100к файлов соединение может разорваться раньше, чем сервер успеет отдать список имен.
← На главную