При разработке интеграций в 1С часто возникает задача сформировать данные в формате JSON на сервере и сохранить их в файл на диске или передать на компьютер пользователя (клиент). Разберем типичную ситуацию, с которой сталкиваются разработчики: код отрабатывает без ошибок, но на выходе получается абсолютно пустой текстовый или JSON-файл. Выясним причину такого поведения и рассмотрим правильные подходы к записи JSON.
Проанализируем классическую ошибку — для выявления подобных проблем в коде пригодится инструмент пошаговой отладки кода 1С. Разработчик инициализирует объект ЗаписьJSON, вызывает метод УстановитьСтроку(), формирует данные и закрывает запись, получая строку. Затем создается пустое имя временного файла, и разработчик сразу пытается прочитать из него ДвоичныеДанные, чтобы передать их во временное хранилище.
Главная ошибка кроется в том, что в сам временный файл на диске данные еще не были записаны! В памяти сервера строка существует, но файл остается пустым. Посмотрим, как правильно решить эту задачу (что полезно, например, при выгрузке в Google Таблицы) несколькими способами — для этого подойдёт автоматическая выгрузка данных 1С в JSON для обмена.
Если нашей конечной целью является создание файла на диске (или во временном каталоге сервера), лучше всего использовать потоковую запись прямо в файл. Для этого вместо метода УстановитьСтроку() следует использовать ОткрытьФайл().
Рассмотрим подробнее параметры этого метода:
Ложь (это правило актуально и для конвертации CSV).Пример правильного кода для прямой записи:
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("json");
ЗаписьJSON = Новый ЗаписьJSON;
// Открываем файл напрямую без BOM
ЗаписьJSON.ОткрытьФайл(ИмяВременногоФайла, "UTF-8", Ложь);
// Здесь может быть сериализация массива или структуры
ЗаписатьJSON(ЗаписьJSON, ДанныеМассива);
// Закрываем файл, данные физически сохраняются на диск
ЗаписьJSON.Закрыть();
Чтобы записанный файл не выглядел как одна длинная нечитаемая строка, добавим структуру с отступами и переносами строк. Проанализируем объект ПараметрыЗаписиJSON. Мы можем настроить символы переноса строк и отступов (табуляция или пробелы), чтобы файл было удобно читать человеку.
ПараметрыФорматирования = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Windows, " ", ДанныеФорматированияJSON.Истина);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ИмяВременногоФайла, "UTF-8", Ложь);
// Передаем параметры форматирования при записи
ЗаписатьJSON(ЗаписьJSON, ДанныеМассива, ПараметрыФорматирования);
ЗаписьJSON.Закрыть();
Что делать, если по логике алгоритма вам необходимо сначала получить саму строку (например, для логирования в регистр сведений или отправки в теле HTTP-запроса), а уже потом сохранить этот же JSON в файл? В этом случае не нужно заново формировать JSON. Разберем использование объекта ЗаписьТекста.
После того как вы получили строку через ЗаписьJSON.Закрыть(), просто запишите ее как обычный текст:
// Получаем строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеМассива);
ПолученнаяСтрокаJSON = ЗаписьJSON.Закрыть();
// Пишем готовую строку в файл
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("json");
ТекстовыйФайл = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8, , Ложь); // Ложь - без BOM
ТекстовыйФайл.Записать(ПолученнаяСтрокаJSON);
ТекстовыйФайл.Закрыть();
Теперь соберем весь процесс воедино и посмотрим, как сформировать файл на сервере и безопасно передать его пользователю для сохранения. Используем механизм временного хранилища.
Код на стороне сервера:
&НаСервере
Функция СформироватьИПоместитьВХранилище()
// 1. Получаем путь к временному файлу на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("json");
// 2. Выполняем запись JSON прямо в этот файл
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ИмяВременногоФайла, "UTF-8", Ложь);
ЗаписатьJSON(ЗаписьJSON, ПолучитьДанныеДляВыгрузки());
ЗаписьJSON.Закрыть();
// 3. Читаем сформированный файл в двоичные данные
ДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
// 4. Помещаем во временное хранилище и возвращаем адрес
АдресВХранилище = ПоместитьВоВременноеХранилище(ДанныеФайла, УникальныйИдентификатор);
Возврат АдресВХранилище;
КонецФункции
Код на стороне клиента:
&НаКлиенте
Процедура СкачатьФайлJSON(Команда)
Адрес = СформироватьИПоместитьВХранилище();
Если ПустаяСтрока(Адрес) Тогда
Возврат;
КонецЕсли;
// В современных версиях 1С используем асинхронные методы сохранения
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеСохраненияФайла", ЭтотОбъект);
ПараметрыСохранения = Новый ПараметрыДиалогаПолученияФайлов;
ПараметрыСохранения.Заголовок = "Сохранить файл JSON";
НачатьПолучениеФайлаССервера(Адрес, "ВыгрузкаДанных.json", ПараметрыСохранения);
КонецПроцедуры
Подведем итог: чтобы файл не получался пустым, необходимо физически записать в него данные с помощью ОткрытьФайл() или через объект ЗаписьТекста, и только после закрытия записи считывать этот файл через ДвоичныеДанные для передачи клиенту — а для отправки готового файла внешним получателям пригодится модуль автоматической рассылки файлов из 1С.