Почему метод FTPСоединение.НайтиФайлы в 1С возвращает пустой массив и как это исправить?

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

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

Разбор кейса: ошибка в динамическом формировании имени файла

Сначала проанализируем ситуацию, описанную в исходном вопросе. Автор пытался найти файл на удаленном сервере по динамическому пути:


НайденныйФайл = Соединение.НайтиФайлы(
     "/medresurs.pro/sites/vigr-sait/" + ФайлТрехдневнойДавности        
);

Поскольку массив НайденныйФайл оказывался пустым, программа обходила цикл обработки. В процессе отладки выяснилась классическая причина: несовпадение строкового формата. Переменная ФайлТрехдневнойДавности формировалась в коде на основе даты с использованием точек в качестве разделителей (например, "26.03.18.csv"), в то время как на самом FTP-сервере файл был сохранен без точек в дате (например, "260318.csv").

Для того чтобы избежать подобных расхождений, всегда важно приводить форматирование дат к единому стандарту, согласованному с принимающей или отправляющей стороной. Напомним, как правильно сформировать строку даты без разделителей в 1С:


// Форматируем дату для получения строки вида "ДДММГГ" (например, "260318")
ИмяФайлаБезТочек = Формат(РабочаяДата, "ДФ=ddMMyy") + ".csv";

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

1. Влияние режима соединения: Активный против Пассивного

Это одна из наиболее частых сетевых проблем. Если соединение и авторизация проходят успешно, но метод НайтиФайлы() «зависает» или сразу возвращает пустой результат, дело практически всегда в брандмауэрах (firewalls), роутерах с NAT или провайдерских ограничениях.

По умолчанию при активном режиме FTP-клиент сообщает серверу свой IP-адрес и порт, после чего сервер сам пытается инициировать обратное TCP-соединение для передачи данных (включая список файлов). Сетевые экраны на стороне клиента обычно блокируют такие входящие соединения.

Решение: Всегда принудительно используем пассивный режим работы. В этом режиме клиент сам открывает порты как для команд, так и для получения данных. Для включения пассивного режима необходимо передать значение Истина в шестой параметр конструктора объекта FTPСоединение:


// Параметры конструктора: Адрес, Порт, Пользователь, Пароль, Прокси, ПассивныйРежим
Соединение = Новый FTPСоединение("ftp.example.com", 21, "user", "password", , Истина);

2. Правильное разделение пути и маски поиска

В исходном примере кода путь к каталогу и имя файла были соединены в один общий строковый параметр:


// Не рекомендуется
НайденныйФайл = Соединение.НайтиФайлы("/medresurs.pro/sites/vigr-sait/260318.csv");

Хотя синтаксис допускает передачу полного пути в качестве первого аргумента, на практике различные типы FTP-серверов (особенно под управлением редких ОС или кастомных FTP-демонов) могут некорректно парсить такую строку. Надежнее и правильнее разделять путь к каталогу и маску поиска на два самостоятельных параметра:


ПутьККаталогу = "/medresurs.pro/sites/vigr-sait/";
МаскаПоиска = "260318.csv"; // или "*.csv" для поиска всех файлов данного типа

// Рекомендуемый способ вызова метода
НайденныйФайл = Соединение.НайтиФайлы(ПутьККаталогу, МаскаПоиска);

Обратите внимание, что путь к каталогу должен обязательно завершаться прямым слешем /.

3. Использование позиционирования через УстановитьТекущийКаталог()

Чтобы минимизировать вероятность ошибок разбора путей, воспользуемся лучшей практикой разработки в 1С. Вместо указания полных абсолютных путей внутри метода НайтиФайлы() выполним предварительный переход в нужную директорию.

Разберем этот алгоритм по шагам:

  1. Устанавливаем соединение с сервером.
  2. Переходим в целевой каталог с помощью метода УстановитьТекущийКаталог().
  3. Вызываем метод НайтиФайлы(), передавая в качестве пути пустую строку "", а в качестве маски — имя искомого файла.

Посмотрим на пример практической реализации данного подхода:


Соединение = Новый FTPСоединение("ftp.medresurs.pro", , "user", "password", , Истина);

// Переходим в нужную папку на сервере
Попытка
    Соединение.УстановитьТекущийКаталог("/sites/vigr-sait/");
Исключение
    ЗаписьЖурналаРегистрации("FTP.Ошибка", УровеньЖурналаРегистрации.Ошибка, , , 
        "Не удалось перейти в указанный каталог: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// Ищем файл в текущем каталоге
НайденныеФайлы = Соединение.НайтиФайлы("", "260318.csv");

Если НайденныеФайлы.Количество() > 0 Тогда
    Для Каждого Файл Из НайденныеФайлы Цикл
        // Обрабатываем найденный файл
        Соединение.Получить(Файл.ПолноеИмя, "C:\Temp\" + Файл.Имя);
    КонецЦикла;
Иначе
    Сообщить("Файл в текущем каталоге не найден!");
КонецЕсли;

4. Чувствительность к регистру символов (Case Sensitivity)

Большинство хостинг-провайдеров и веб-ресурсов работают под управлением операционных систем на базе ядра Linux/Unix. В отличие от ОС Windows, файловые системы Linux строго чувствительны к регистру символов. Для них файлы "file.csv", "file.CSV" и "File.csv" — это три абсолютно разных файла.

Если в коде 1С вы ищете маску "*.CSV", а на сервере лежат файлы с расширением в нижнем регистре (.csv), метод НайтиФайлы() вернет пустой массив. Обязательно проверяйте регистр символов как в путях к папкам, так и в расширениях файлов.

5. Использование исключительно прямых слешей

В операционной системе Windows в качестве разделителя путей используется обратный слеш \. Однако протокол FTP базируется на стандартах URI, где разделителем директорий может выступать только прямой слеш /.

Если вы динамически собираете путь, используя системные функции или константы 1С (например, содержащие локальные пути Windows), в строку могут просочиться символы \. FTP-сервер не сможет интерпретировать такой путь и вернет ошибку либо пустой массив. Перед вызовом методов FTP всегда проверяйте строку пути и при необходимости выполняйте замену символов:


// Очищаем путь от возможных обратных слешей
ИсправленныйПуть = СтрЗаменить(ИсходныйПуть, "\", "/");

6. Специфика прав доступа: блокировка листинга каталога

Бывают ситуации, когда на FTP-сервере настроены жесткие политики безопасности. Администратор сервера может предоставить вашей учетной записи права на чтение конкретного файла (команда RETR) или запись (команда STOR), но запретить просмотр содержимого папки (команды листинга LIST или MLSD).

В этом случае:

Проанализируем пример прямого скачивания файла без вызова поиска:


// Если мы точно знаем, что файл должен быть на сервере, скачиваем его напрямую
Попытка
    Соединение.Получить("/sites/vigr-sait/260318.csv", "C:\LocalFolder\260318.csv");
    Сообщить("Файл успешно скачан напрямую!");
Исключение
    Сообщить("Не удалось скачать файл. Возможно, он отсутствует: " + ОписаниеОшибки());
КонецПопытки;

7. Проблема кодировки имен файлов

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

Рекомендация: При проектировании систем интеграции и обмена данными через FTP старайтесь полностью исключать кириллицу, пробелы и спецсимволы из наименований файлов и папок. Используйте только латиницу, цифры, знаки подчеркивания и дефисы.

← На главную