К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как прочитать файл из временного хранилища

Как прочитать файл из временного хранилища в 1С: ПолучитьИзВременногоХранилища, работа с двоичными данными, тонкий и веб-клиент, типовые ошибки и примеры кода.

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

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

Материал ориентирован на управляемые формы и платформу 8.3, где вся работа с файлами строится через асинхронные методы и передачу данных между клиентом и сервером. Примеры кода приведены на встроенном языке 1С.

Что такое временное хранилище и как в него попадает файл

Временное хранилище — это область памяти на сервере 1С, куда можно поместить произвольное значение и получить взамен адрес (строку). Живут данные там ограниченное время: либо до конца вызова сервера, либо до конца сеанса, либо до удаления формы-владельца — в зависимости от того, какое значение передано вторым параметром метода ПоместитьВоВременноеХранилище.

Когда пользователь выбирает файл через НачатьПомещениеФайла или перетаскивание, платформа сама помещает двоичные данные файла в хранилище и передаёт в обработчик адрес. Именно этот адрес обычно хранится в реквизите формы, например АдресФайла. Важно понимать: на клиенте содержимого файла уже нет, есть только ссылка на серверные данные.

Базовый способ: ПолучитьИзВременногоХранилища

Основной метод чтения — ПолучитьИзВременногоХранилища(Адрес). Он возвращает значение, которое было помещено в хранилище. Для файлов это всегда объект типа ДвоичныеДанные. Вызов выполняется на сервере, поэтому код размещают в серверной процедуре формы или в серверном модуле.

Минимальный пример чтения и записи во временный файл:

&НаСервере

Процедура ПрочитатьФайлНаСервере()

ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайла);

ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");

ДвоичныеДанные.Записать(ИмяВременногоФайла);

// дальше файл доступен по пути ИмяВременногоФайла

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

После записи во временный файл с ним можно работать привычными средствами: ТабличныйДокумент.Прочитать() для Excel, ЧтениеТекста для текстовых файлов, ЧтениеXML для XML. По окончании обработки временный файл стоит удалить через УдалитьФайлы(ИмяВременногоФайла), иначе каталог временных файлов сервера будет расти.

Порядок чтения файла из хранилища
  1. 1
    Проверьте, что адрес не пустой: ЭтоАдресВременногоХранилища(АдресФайла)
  2. 2
    На сервере вызовите ПолучитьИзВременногоХранилища(АдресФайла) и получите ДвоичныеДанные
  3. 3
    Сформируйте имя временного файла с нужным расширением через ПолучитьИмяВременногоФайла()
  4. 4
    Запишите данные: ДвоичныеДанные.Записать(ИмяФайла)
  5. 5
    Обработайте файл подходящим объектом (ТабличныйДокумент, ЧтениеТекста, ЧтениеXML)
  6. 6
    Удалите временный файл и при необходимости очистите хранилище через УдалитьИзВременногоХранилища

Чтение без записи на диск: работа с потоками

Запись во временный файл — не единственный путь. Начиная с версий платформы, поддерживающих потоки, двоичные данные можно открыть как поток и читать напрямую из памяти: Поток = ДвоичныеДанные.ОткрытьПотокДляЧтения(). Это быстрее и не оставляет мусора на диске сервера.

Потоки удобны для построчного разбора текстовых данных, чтения через ЧтениеДанных или передачи содержимого дальше — например, в HTTP-запрос. Однако часть объектов платформы (например, ТабличныйДокумент.Прочитать) исторически требует именно файл на диске, поэтому для Excel чаще всего всё равно приходится записывать временный файл.

Два подхода к чтению данных

Запись во временный файл

Универсально: подходит для Excel, XML, картинок и любых объектов, требующих путь. Минус — лишние файловые операции и необходимость удалять файл.

Чтение через поток

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

Как долго живёт адрес и когда данные пропадают

Самая частая причина «файл не читается» — истёк срок жизни значения в хранилище. Если файл помещён вызовом ПоместитьВоВременноеХранилище без второго параметра, данные удаляются сразу после завершения серверного вызова. При следующем обращении по адресу метод вернёт Неопределено или вызовет ошибку.

Чтобы адрес жил, пока открыта форма, вторым параметром передают уникальный идентификатор формы: ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификаторФормы). При интерактивном помещении файла через НачатьПомещениеФайла платформа обычно привязывает значение к форме автоматически, но при программном помещении это нужно контролировать самостоятельно.

Особенности тонкого и веб-клиента

На тонком и веб-клиенте нельзя напрямую читать файлы с диска пользователя синхронными методами — работа строится через НачатьПомещениеФайла с описанием оповещения. В обработчике приходит адрес хранилища, который затем передаётся в серверную процедуру чтения. Схема одинакова для обоих клиентов, различий в серверном коде нет.

На веб-клиенте есть ограничение по размеру передаваемого файла, зависящее от настроек веб-сервера и браузера. Большие файлы (сотни мегабайт) могут не загружаться целиком или приводить к тайм-ауту. В таких случаях файл разбивают на части или загружают штатными средствами внешних компонент. Также в веб-клиенте недоступен ТабличныйДокумент.Прочитать на клиенте — чтение Excel всегда выполняется на сервере.

Проверка результата и контроль ошибок

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

Контрольные точки

Как проверить результат чтения

ЭтоАдресВременногоХранилища(Адрес)
Норма

Возвращает Истина — адрес валиден

Тревожный признак

Ложь — адрес пуст или данные уже удалены

Результат ПолучитьИзВременногоХранилища
Норма

Объект типа ДвоичныеДанные с ненулевым размером

Тревожный признак

Неопределено — срок жизни значения истёк

Файл после ДвоичныеДанные.Записать()
Норма

Файл существует, размер совпадает с размером данных

Тревожный признак

Файл отсутствует или имеет нулевой размер

Полезно оборачивать чтение и разбор в попытку-исключение с понятным текстом ошибки для пользователя. Сообщение вида «Не удалось прочитать файл: истёк срок хранения, выберите файл повторно» экономит часы разбора обращений, потому что пользователь сразу понимает, что нужно сделать.

Типичные ошибки и как их избежать

Типичные ошибки при чтении из хранилища
01
Попытка открыть адрес хранилища как путь к файлу через ЧтениеТекста или ТабличныйДокумент.Прочитать — адрес не является файлом, сначала нужно получить двоичные данные
02
Чтение в другом серверном вызове без привязки к форме — данные уже удалены, метод возвращает Неопределено
03
Запись временного файла без расширения — последующий разбор Excel или XML падает с ошибкой формата
04
Выполнение ПолучитьИзВременногоХранилища на клиенте в контексте, где метод недоступен — чтение должно идти на сервере
05
Отсутствие удаления временных файлов — каталог временных файлов сервера постепенно переполняется
06
Игнорирование кодировки при чтении текстовых файлов через поток — русские буквы превращаются в нечитаемые символы

Отдельно стоит ситуация с фоновыми заданиями. Если файл нужно обработать в фоне, адрес хранилища можно передать в фоновое задание параметром, но только если значение привязано к форме и форма останется открытой до завершения задания. Более надёжный вариант — прочитать двоичные данные до запуска фонового задания и передать их через хранилище значения в параметрах или сохранить файл в каталог, доступный серверу.

Альтернативы временному хранилищу

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

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

Итог

Что важно запомнить

Адрес временного хранилища — не путь к файлу. Чтение выполняется на сервере через ПолучитьИзВременногоХранилища, результат — ДвоичныеДанные, которые записывают во временный файл с правильным расширением или читают через поток. Контролируйте срок жизни значения привязкой к форме и проверяйте результат на Неопределено.

Частые вопросы

Можно ли прочитать файл из временного хранилища на клиенте?

Метод ПолучитьИзВременногоХранилища доступен и на клиенте в управляемых формах, однако разбор файла (Excel, XML) обычно всё равно выполняют на сервере — там доступны все объекты платформы и нет ограничений веб-клиента. Практичнее сразу передавать адрес в серверную процедуру.

Почему ПолучитьИзВременногоХранилища возвращает Неопределено?

Значение уже удалено: либо завершился серверный вызов, в котором оно было помещено без привязки к форме, либо форма-владелец закрыта, либо данные удалены явно. Перепоместите файл с передачей УникальныйИдентификатор формы вторым параметром.

Как узнать имя и расширение исходного файла?

Из хранилища — никак, там только двоичные данные. Имя файла возвращается в обработчик оповещения НачатьПомещениеФайла или доступно в элементе формы выбора файла. Сохраните его в отдельный реквизит формы при загрузке.

Нужно ли удалять данные из хранилища после чтения?

Если значение привязано к форме, платформа удалит его при закрытии формы. Явный вызов УдалитьИзВременногоХранилища имеет смысл после успешной обработки, чтобы не держать большие файлы в памяти сервера, пока форма открыта.

Можно ли передать адрес хранилища в фоновое задание?

Да, адрес передаётся как обычный строковый параметр. Но значение должно жить до конца задания: привяжите его к форме и не закрывайте форму до завершения обработки. Надёжнее — прочитать данные заранее и передать их через ХранилищеЗначения.

Чем отличается ПоместитьВоВременноеХранилище от НачатьПомещениеФайла?

Первый метод помещает в хранилище любое значение, уже существующее в программе. Второй — интерактивно загружает файл с диска пользователя и сам кладёт его двоичные данные в хранилище, возвращая адрес. Чтение в обоих случаях одинаковое.