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

Процесс передачи подразумевает чтение файла в локальном потоке клиента и его запись в поток на стороне сервера. Важно понимать, что при работе в файловом варианте базы данных клиент и сервер физически могут находиться на одной машине, но логически разделены. В клиент-серверном варианте с MS SQL Server или PostgreSQL разделение становится абсолютным, и прямой доступ к дискам сервера из кода клиента невозможен без специальных процедур.

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

Архитектура работы с файлами в клиент-серверном режиме

Фундаментальным ограничением платформы является изоляция контекстов выполнения. Код, выполняющийся на стороне клиента, не имеет прямого доступа к файловой системе сервера баз данных. Попытка указать путь вида C:\ServerData\Import в методе ПоместитьФайл из клиентского контекста приведет к ошибке, так как клиентская машина этот путь не увидит или не сможет записать туда данные напрямую.

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

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

⚠️ Внимание: При передаче файлов размером более 100 МБ через параметры серверных вызовов возможно существенное снижение производительности системы. В таких случаях рекомендуется разбивать файл на части или использовать потоковую передачу через временные хранилища.
💡

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

Использование объекта ДвоичныеДанные для прямого обмена

Наиболее универсальный способ передачи — использование встроенного объекта ДвоичныеДанные. Этот объект представляет собой обертку над байтовым массивом, которую платформа умеет корректно сериализовать и передавать между клиентом и сервером. Процесс начинается с чтения файла на клиенте в этот объект.

После получения объекта на клиенте необходимо вызвать серверную функцию, передав ей считанные данные. На сервере вы принимаете этот параметр и используете метод Записать для сохранения содержимого по целевому пути.

Данный метод идеально подходит для документов среднего размера: сканов договоров, печатных форм, небольших архивов. Он не требует настройки дополнительного ПО и работает «из коробки» в любой конфигурации, будь то Управление торговлей или самописная разработка.

📊 Какой размер файлов вы чаще всего передаете в 1С?
До 1 МБ
От 1 до 10 МБ
От 10 до 100 МБ
Более 100 МБ

Код реализации выглядит достаточно лаконично. На клиенте вы создаете объект, читаете файл и вызываете сервер. На сервере просто сохраняете. Однако стоит учитывать, что весь файл целиком попадает в оперативную память процесса.

&НаКлиенте

Процедура ЗагрузитьФайлНаСервер(ПутьКФайлу)

ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);

СохранитьНаСервере(ДвоичныеДанныеФайла, "ИмяФайла.dat");

КонецПроцедуры

&НаСервере

Процедура СохранитьНаСервере(Данные, ИмяФайла)

Данные.Записать("C:\1C_Data\Upload\" + ИмяФайла);

КонецПроцедуры

Работа с временными хранилищами файлов

В некоторых сценариях, особенно при работе с большими объемами данных или при необходимости асинхронной обработки, использование прямых параметров вызова может быть неэффективным. Здесь на помощь приходит механизм ВременныхХранилищФайлов. Этот инструмент позволяет загрузить файл в специальное хранилище на сервере, получив взамен уникальный идентификатор (ссылку).

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

Ссылка на временное хранилище имеет срок жизни, который можно настроить. Если файл не будет востребован в течение заданного времени, он будет автоматически удален службой очистки. Это удобно для организации процессов, где файл является промежуточным этапом, например, при загрузке табличного документа перед проведением документа.

Параметр Описание Рекомендуемое значение
ИмяФайла Оригинальное имя загружаемого файла Любое допустимое
УдалитьЧерез Время жизни файла в хранилище 3600 секунд (1 час)
Защищено Доступ только для создавшего сеанса Истина (для безопасности)
Расширение Тип файла для корректной обработки Соответствует исходному

Использование временных хранилищ также позволяет реализовать сценарий, когда клиент загружает файл, а серверная фоновая задача (фоновое задание) обрабатывает его спустя некоторое время. Ссылка передается в задание, и исполнитель получает доступ к данным без необходимости повторной загрузки.

Где физически хранятся временные файлы?

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

Передача через сетевые ресурсы и общие папки

Альтернативный подход, который часто применяется в крупных внедрениях, заключается в использовании общей сетевой папки (SMB/CIFS). В этом сценарии 1С выступает лишь как инициатор копирования, а сама передача данных осуществляется средствами операционной системы. Клиент копирует файл в общую папку, доступную серверу 1С для чтения.

Такой метод снимает нагрузку с процесса сервера 1С, так как он не участвует в транспортировке байтов через свой внутренний протокол. Сервер 1С просто периодически опрашивает папку \\FileServer\1C_Import и забирает оттуда новые файлы. Это особенно актуально для интеграции с внешним оборудованием или другими системами.

Для реализации этого способа необходимо настроить права доступа в Windows. Учетная запись, от имени которой запущен сервис 1С, должна иметь права на чтение и запись в эту сетевую папку. Кроме того, клиентские машины пользователей также должны иметь доступ к этой шаре для выгрузки.

⚠️ Внимание: Конфигурации брандмауэра и антивирусного ПО могут блокировать доступ к сетевым папкам. Убедитесь, что порты SMB (обычно 445) открыты для внутреннего трафика вашей локальной сети.

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

☑️ Настройка общей папки

Выполнено: 0 / 4

Использование HTTP-сервисов для внешней загрузки

В современных распределенных системах, где клиенты могут находиться за пределами локальной сети (например, мобильные сотрудники или филиалы), использование прямых сетевых путей или вызовов сервера 1С может быть затруднено из-за настроек безопасности и NAT. В таких случаях оптимальным решением является организация HTTP-сервиса на стороне 1С.

Клиентское приложение (внешнее или веб-клиент) формирует HTTP-запрос типа POST, прикрепляя файл к телу запроса в формате Multipart/form-data. Сервер 1С, принимая этот запрос через опубликованный веб-сервис, извлекает поток данных и сохраняет его. Этот метод является стандартом де-факто для интеграции с веб-сайтами и мобильными приложениями.

Реализация требует настройки веб-сервера (IIS или Apache), который проксирует запросы к серверу 1С. В коде обработчика HTTP-запроса вы работаете с объектом HTTPСервисОтвет и считываете тело запроса как поток. Это дает гибкость в валидации данных перед сохранением.

Такой подход также позволяет реализовать авторизацию и логирование всех операций загрузки на уровне веб-сервера. Вы можете ограничивать размер загружаемых файлов, проверять расширения и фильтровать подозрительный контент до того, как он попадет в файловую систему базы данных.

💡

HTTP-загрузка является наиболее безопасным и масштабируемым способом приема файлов от внешних клиентов и мобильных устройств, так как не требует открытия портов СУБД или доступа к файловой шаре.

Обработка ошибок и логирование процессов

Любая операция ввода-вывода потенциально опасна с точки зрения стабильности системы. Файл может быть занят другим процессом, на диске может закончиться место, или права доступа могут измениться в реальном времени. Поэтому критически важно оборачивать процедуры записи в конструкцию Попытка..Исключение.

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

Особый случай — это работа с именами файлов. Пользователи могут загружать файлы с именами, содержащими недопустимые символы для серверной ОС (например, :, *, ? в Windows). Перед сохранением всегда выполняйте санитизацию имени файла, заменяя опасные символы на подчеркивание или удаляя их.

&НаСервере

Процедура БезопаснаяЗапись(Данные, ИмяФайла)

// Очистка имени от запрещенных символов

БезопасноеИмя = СтрЗаменить(ИмяФайла, ":", "_");

БезопасноеИмя = СтрЗаменить(БезопасноеИмя, "\", "_");

Попытка

Данные.Записать("C:\Data\" + БезопасноеИмя);

Исключение

ЗаписьЖурналаРегистрации("ЗагрузкаФайлов", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());

ВызватьИсключение "Не удалось сохранить файл. Проверьте права доступа.";

КонецПопытки;

КонецПроцедуры

Также рекомендуется проверять свободное место на целевом диске перед началом массовой загрузки. Хотя 1С не имеет прямой функции для этого в кроссплатформенном виде, в среде Windows можно использовать внешние компоненты или вызовы системных утилит для получения этой информации.

⚠️ Внимание: Никогда не используйте имена файлов, полученные напрямую от пользователя, без предварительной проверки. Это может привести к уязвимостям типа Path Traversal, когда злоумышленник пытается записать файл в системную директорию.

Часто задаваемые вопросы

Можно ли передать файл напрямую из веб-клиента в браузере?

Да, веб-клиент поддерживает работу с файловой системой через специальные диалоги выбора файла. Однако сам файл сначала загружается в браузер, а затем передается на сервер 1С через HTTP-протокол. Прямой доступ к диску пользователя из браузера запрещен политиками безопасности.

Какой максимальный размер файла можно передать через ДвоичныеДанные?

Технического жесткого ограничения в платформе нет, оно ограничено доступной оперативной памятью процесса сервера 1С и настройками кластера. На практике стабильная передача возможна для файлов до 500 МБ. Для больших объемов используйте потоковую запись или сетевые шары.

Как передать файл, если сервер 1С работает на Linux?

Принцип работы с объектом ДвоичныеДанные идентичен. Единственное отличие — пути к файлам. Используйте прямые слеши / и учитывайте регистр имен файлов, так как файловая система Linux чувствительна к регистру (в отличие от Windows).

Нужно ли закрывать потоки после записи файла?

При использовании методов объекта ДвоичныеДанные (например, Записать) управление потоками происходит автоматически внутри метода. Вам не нужно явно закрывать потоки, если вы не открывали их самостоятельно через ПотокВПамяти или ФайловыйПоток.