Зачастую при разработке регламентных заданий, работающих на стороне сервера (особенно в облачных средах, таких как 1С:ГРМ или 1С:Фреш), программисты сталкиваются с тем, что код, отлично работающий в файловой версии базы, на сервере вызывает ошибки. Одной из наиболее частых проблем является невозможность записи временных файлов на диск или ошибки при работе с FTPСоединение. Давайте разберемся, почему это происходит и как правильно передавать данные на FTP-сервер без лишних проблем с доступом к файловой системе.
Основная причина заключается в том, что в клиент-серверном варианте код выполняется от имени учетной записи системного пользователя сервера (например, usr1cv8 в Linux). Этот пользователь зачастую не имеет прав на запись в системные каталоги временных файлов или в папки, к которым мы привыкли при разработке на локальной машине. Использование КаталогВременныхФайлов в таких условиях — это путь к ошибкам доступа. Наиболее надежным способом решения задачи является работа с данными исключительно в оперативной памяти с помощью механизмов ПотокВПамяти.
Самый элегантный и производительный способ — не создавать физический файл на диске сервера, а передать данные сразу из оперативной памяти в объект FTPСоединение. Рассмотрим этот подход по шагам:
ПотокВПамяти, в который запишем наш табличный документ.PDF.FTPСоединение может отправить пустой файл, так как после записи данных указатель потока находится в самом конце.Записать объекта FTPСоединение.Давайте посмотрим на пример реализации:
ВрПотокВпамяти = Новый ПотокВПамяти;
ТабДок.Записать(ВрПотокВпамяти, ТипФайлаТабличногоДокумента.PDF);
// Критически важный момент: возвращаем указатель в начало потока
ВрПотокВпамяти.Перейти(0, ПозицияВПотоке.Начало);
Соединение = Новый FTPСоединение("Сервер", 21, "Логин", "Пароль", , Истина, 100);
Соединение.Записать("ИмяФайла.pdf", ВрПотокВпамяти);
Если по какой-то причине вы предпочитаете работать через промежуточный объект потока для чтения, вы можете извлечь ДвоичныеДанные из потока памяти, а затем открыть поток для чтения. Этот метод также отлично работает в серверном окружении.
ВрПотокВпамяти = Новый ПотокВПамяти;
ТабДок.Записать(ВрПотокВпамяти, ТипФайлаТабличногоДокумента.PDF);
ДвоичныеДанные = ВрПотокВпамяти.ЗакрытьИПолучитьДвоичныеДанные();
ВрПоток = ДвоичныеДанные.ОткрытьПотокДляЧтения();
Соединение = Новый FTPСоединение("Сервер", 21, "Логин", "Пароль", , Истина, 100);
Соединение.Записать("ИмяФайла.pdf", ВрПоток);
Чтобы ваш код был по-настоящему надежным и не вызывал проблем в процессе эксплуатации, обратите внимание на следующие моменты:
Попытка...Исключение при работе с внешними соединениями. FTP-сервер может быть недоступен, логин/пароль могут измениться, или сеть может кратковременно прерваться.Закрыть() у объектов потоков. Это поможет избежать утечек дескрипторов файлов и блокировок данных на сервере.Поток и ДвоичныеДанные гарантирует отсутствие ошибок доступа к файловой системе сервера.Подводя итог, проанализируем ситуацию: использование ПотокВПамяти исключает зависимость от прав доступа к диску, делая ваше решение универсальным и переносимым между любыми вариантами развертывания 1С. Это современный и профессиональный подход к решению задачи интеграции с внешними FTP-ресурсами.