При работе с выгрузкой данных из 1С на FTP-сервер часто возникает задача автоматической отправки файлов. Стандартный объект FTPСоединение предоставляет для этого все необходимые инструменты. Однако иногда, несмотря на успешное подключение к серверу, попытка записать файл завершается неудачей без внятного сообщения об ошибке. Проанализируем типичную ситуацию: соединение устанавливается, но метод Записать() не выполняется, и файл на сервере не появляется. Выясним, в чем может быть причина и как это исправить.
Рассмотрим исходный код, который приводит к проблеме. Автор пытается подключиться к FTP и записать файл следующим образом:
Попытка
FTPСоединение = Новый FTPСоединение(СерверFTP,ПортFTP,ПользовательFTP,ПарольFTP);
Исключение
Сообщить("Не удалось установить FTP соединение!");
Возврат;
КонецПопытки;
FTPСоединение.Записать(ПолныйПутьКФайлу, ИмяФайлаНаСервере);
FTPСоединение = Неопределено;
На первый взгляд, код выглядит корректно. Создается объект FTPСоединение с необходимыми параметрами, а затем вызывается метод Записать(). Проблема в том, что по умолчанию 1С пытается установить активное FTP-соединение. В этом режиме сервер инициирует соединение с клиентом для передачи данных. Большинство современных сетевых инфраструктур, включая брандмауэры и NAT, блокируют такие входящие соединения из соображений безопасности. В результате соединение для передачи данных не устанавливается, и файл не загружается.
Решением является использование пассивного режима FTP. В этом режиме клиент сам инициирует соединение для передачи данных, что, как правило, разрешено сетевыми политиками. В 1С за это отвечает свойство ПассивноеСоединение.
Чтобы гарантированно записать файл на сервер, необходимо явно указать 1С использовать пассивный режим. Для этого после создания объекта FTPСоединение и перед вызовом метода Записать() нужно установить свойство ПассивноеСоединение в значение Истина.
Давайте по шагам разберем исправленный и дополненный код.
Сначала создаем новый экземпляр объекта FTPСоединение, передавая ему адрес сервера, порт, логин и пароль. Весь этот блок лучше обернуть в конструкцию Попытка-Исключение, чтобы отловить возможные ошибки подключения (неверный адрес, порт, проблемы с сетью).
// Определяем параметры подключения
СерверFTP = "ftp.example.com";
ПортFTP = 21;
ПользовательFTP = "user";
ПарольFTP = "password";
ПолныйПутьКФайлу = "C:\temp\upload.zip";
ИмяФайлаНаСервере = "upload.zip";
Попытка
// Создаем объект соединения
FTPСоединение = Новый FTPСоединение(СерверFTP, ПортFTP, ПользовательFTP, ПарольFTP);
Исключение
Сообщить("Не удалось установить FTP соединение! " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Это ключевой шаг, который решает исходную проблему. Устанавливаем соответствующее свойство в Истина.
// Устанавливаем пассивный режим для обхода брандмауэров
FTPСоединение.ПассивноеСоединение = Истина;
Теперь вызываем метод Записать(). Он принимает два параметра: первый — это полный путь к файлу на локальном компьютере, который нужно загрузить, а второй — имя, под которым файл будет сохранен на FTP-сервере. Эту операцию также стоит обернуть в Попытка-Исключение, чтобы обработать возможные ошибки, связанные с правами доступа на запись в целевой каталог или нехваткой места на сервере.
Попытка
FTPСоединение.Записать(ПолныйПутьКФайлу, ИмяФайлаНаСервере);
Сообщить("Файл успешно загружен на FTP-сервер.");
Исключение
Сообщить("Ошибка при записи файла на FTP: " + ОписаниеОшибки());
КонецПопытки;
После выполнения всех операций важно освободить ресурсы, присвоив переменной FTPСоединение значение Неопределено. Это закроет соединение с сервером.
FTPСоединение = Неопределено;
Для более надежной работы рекомендуется также проверять существование каталога на FTP-сервере и создавать его при необходимости. Это можно сделать с помощью метода СоздатьКаталог().
Ниже представлен полный, готовый к использованию пример функции для выгрузки файла на FTP с учетом всех рекомендаций.
Процедура ВыгрузитьФайлНаFTP()
// Параметры
СерверFTP = "ftp.example.com";
ПортFTP = 21;
ПользовательFTP = "user";
ПарольFTP = "password";
ЛокальныйФайл = "C:\temp\data.xml";
УдаленныйПуть = "/uploads/data.xml";
// Инициализация переменной
FTPСоединение = Неопределено;
// Основной блок работы с FTP
Попытка
// 1. Установка соединения
FTPСоединение = Новый FTPСоединение(СерверFTP, ПортFTP, ПользовательFTP, ПарольFTP, , , Истина); // Последний параметр - таймаут
// 2. Включение пассивного режима (важнейший шаг)
FTPСоединение.ПассивноеСоединение = Истина;
// 3. (Опционально) Проверка и создание каталога на сервере
// Например, если нужно положить файл в папку /uploads
// В данном примере мы этого не делаем, но можно раскомментировать
// Попытка
// FTPСоединение.УстановитьТекущийКаталог("/uploads");
// Исключение
// // Если каталога нет, создаем его
// FTPСоединение.СоздатьКаталог("/uploads");
// КонецПопытки;
// 4. Запись файла
FTPСоединение.Записать(ЛокальныйФайл, УдаленныйПуть);
Сообщить("Файл '" + ЛокальныйФайл + "' успешно выгружен в '" + УдаленныйПуть + "'");
Исключение
Сообщить("Произошла ошибка при работе с FTP: " + ОписаниеОшибки());
КонецПопытки;
// 5. Закрытие соединения
Если FTPСоединение <> Неопределено Тогда
FTPСоединение = Неопределено;
КонецЕсли;
КонецПроцедуры
Таким образом, основная причина неудачной записи файла на FTP-сервер при рабочем подключении — это блокировка активного режима соединения. Простое добавление строки FTPСоединение.ПассивноеСоединение = Истина; перед вызовом метода записи решает эту проблему в большинстве случаев, обеспечивая стабильную и надежную выгрузку файлов из 1С.