Альтернативное получение значения из хранилища значения. Свой ХранилищеЗначения.Получить();

22.04.19

Интеграция - Файловый обмен (TXT, XML, DBF), FTP

Данная публикация не претендует на использование в продакшене, но когда "Нельзя, но очень хочется" в отношении получения ооочень больших данных из ХранилищаЗначения и когда сама платформа не может получить значение и падает, при этом, перед падением съедает почти всю память. Это своего рода костыль, в безвыходной ситуации. Речь пойдет про получение больших данных из хранилища значения в файловых базах на 32-х битной платформе. Данное не касается 64-х битных клиентов/серверов где нет ограничения на размер потребляемой памяти (верней есть, но доступно памяти гораздо больше, чем 32-х битному приложению без PAE).

Скачать файлы

Наименование Файл Версия Размер
Альтернативное получение значения из хранилища значения. Свой ХранилищеЗначения.Получить();:
.epf 12,71Kb
14
.epf 0.1 12,71Kb 14 Скачать

Однажды, когда я был молодой и глупый (последнее правда с тех под и не изменилось), я решал задачу автоматического РИБ обмена через веб-сервис и в качестве контейнера для данных, я решил использовать передачу хранилища значения, в котором упакована с сжатием (9) строка содержимым XML файла сообщения. И всё бы ничего, работало это без проблем. Как вдруг, попался один узел, для которого накопилось ну очень много данных (смотря конечно для кого), а именно, XML данные весили чуть больше 400 Мб. в сжатом виде же это занимало примерно 60 Мб, через интернет клиент веб-сервиса данные то скачал, но при попытке ХранилищеЗначение.Получить(); (База файловая, памяти 2 Гб) 1С сначала кушала память ложками, до без малого 1 Гб съедала и с грохотом падала пугая голубей в соседнем дворе. Конечно, ручной обмен ни-кто не отменял (через классические файлы) и там всё проходило без проблем (как минимум по тому, что 1С не весь файл XML читает в память). Данная проблема воспроизводилась как на релизах 8.3.10.2699 и 8.3.12.1855 так и на других версиях.

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

Я было просто забил на проблему, ибо она редкая и можно обмен сделать ручками, так как просто не представлял как её можно решить, но тут я совершенно случайно наткнулся отличную публикацию: //infostart.ru/public/618906/ от SerVer1C (за что ему огромное спасибо!) и тут понеслось... Итогом этого, стал собственный метод, получающий значение хранилища значений, который по минимуму питается оперативной памятью, предпочитая ей обычный диск и главное, не валящий процесс 1С ну и конечно выполняющий свою задачу ;)

Суть решения "проста", запакованное хранилище значения из себя представляет данные, запакованные алгоритмом Deflate (которая сама 1С использует везде, а доступа к методам дать не могут) и некоторое служебные данные. Этим же методом Deflate, упаковываются ZIP архивы. Итого весь процесс проводится к следующему:

1) Получение из хранилища значений двоичных данных (да-да, 1С не добавила возможности прямого получения):

ДанныеВBase64 = XMLСтрока(ХранилищеЗначения); // Получим Base64 хранилища значения
ДвоичныеДанные = Base64Значение(ДанныеВBase64); // Получаем двоичные данные хранилища значения

2) Получаем буфер двоичных за вычетом префикса хранилища значения

РазмерСлужебногоЗаголовка = 18; // Размер в байтах служебного заголовка хранилища значения
Поток = ДвоичныеДанные.ОткрытьПотокДляЧтения(); // Открываем поток для данных
Поток.Перейти(РазмерСлужебногоЗаголовка, ПозицияВПотоке.Начало); // Прыгаем в начало данных
РазмерПотока = Поток.Размер() - РазмерСлужебногоЗаголовка;
БуферТелаФайла = Новый БуферДвоичныхДанных(РазмерПотока); // Создаем буфер под данные
Поток.Прочитать(БуферТелаФайла, 0, РазмерПотока); // Читаем данные в буфер
Поток.Закрыть();

3) Формируем структуру ZIP архива и добавляем к нему данные из буфера двоичных данных

ДлинаИмениСжатогоФайла		= СтрДлина(ИмяФайлаВАрхиве);
РазмерСжатогоФайла			= РазмерПотока;
... // Подробнее можно ознакомится в приложенном файле и/или в исходной публикации: //infostart.ru/public/618906/
НовыйБинарник = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
НовыйБинарник.Записать(ПутьКФайлуАрхива);
ПотокВПамяти.Закрыть();

4) Распаковать ZIP архив, игнорируя ошибки распаковки (так как у нас нет данных о CRC сумме НЕ запакованных данных, а так же об их размере)

// Можно было и в памяти извлекать, но слишком много памяти кушает
Архив = Новый ЧтениеZipФайла(ПутьКФайлуАрхива);
Попытка
	Архив.Извлечь(Архив.Элементы[0], КаталогОбмена);
	//файл извлечется, хотя здесь возникнет исключение из-за некорректных размера файла и контрольной суммы
Исключение
КонецПопытки;

5) На выходе, мы уже получаем распакованные данные, которые были помещены в хранилище значения, НО, они окружены структурой, похожей на JSON которая всюду используется в 1С как минимум с 1С 7.7 (или даже раньше), для того чтобы от неё избавится, надо в начале файла отрезать чуток и в конце, а так-же убрать экранирование кавычек. Тут я пробовал разные варианты (кроме считывания всего текста и СтрЗаменить, ибо память не безлимитная, но и такой способ работает и 1С не падает), но самым оптимальным как по скорости, так и по потреблению памяти, оказалось порционное чтение из файла, замена двойных кавычек на одинарные и запись в результирующий файл (выполняется мгновенно, пруфов нет)

ПотокЧтения = Новый ФайловыйПоток(ПутьКИзвлеченномуФайлу, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
ЧтениеТекста = Новый ЧтениеТекста(ПотокЧтения, КодировкаТекста.UTF8);
ПотокЗаписи = Новый ФайловыйПоток(ПутьКФайлуРезультата, РежимОткрытияФайла.Создать, ДоступКФайлу.Запись);
ЗаписьТекста = Новый ЗаписьДанных(ПотокЗаписи, КодировкаТекста.UTF8);
БуферТекста = ЧтениеТекста.Прочитать(50*1024*1024); // Делим по 50 мегабайт
ТекущаяПорция = Неопределено;
ПерваяСтрокаСчитана = Ложь;
Пока БуферТекста <> Неопределено Цикл 
	Если ТекущаяПорция <> Неопределено Тогда
		ЗаписьТекста.ЗаписатьСимволы(ТекущаяПорция, КодировкаТекста.UTF8);
		ЗаписьТекста.СброситьБуферы();
	КонецЕсли;
	Если Не ПерваяСтрокаСчитана Тогда
		БуферТекста = Прав(БуферТекста, СтрДлина(БуферТекста) - 15);
		ПерваяСтрокаСчитана = Истина;
	КонецЕсли;
	Если Прав(БуферТекста, 1) = """" Тогда
		// В конце нашли одинокую кавычку, надо её удалить
		БуферТекста = Лев(БуферТекста, СтрДлина(БуферТекста) - 1);
	КонецЕсли;
	ТекущаяПорция = СтрЗаменить(БуферТекста, """""", """");
	БуферТекста = ЧтениеТекста.Прочитать(ДелитьПо);
КонецЦикла;
Если ТекущаяПорция <> Неопределено Тогда
	ТекущаяПорция = СтрЗаменить(ТекущаяПорция, """}", "");
	ЗаписьТекста.ЗаписатьСимволы(ТекущаяПорция, КодировкаТекста.UTF8);
КонецЕсли;
ЧтениеТекста.Закрыть();
ПотокЧтения.Закрыть();
ЗаписьТекста.Закрыть();
ПотокЗаписи.Закрыть();

6) Profit! На выходе мы получаем файл имеющий в точности то же содержимое, что и положили в Хранилище значение. Тут можно и сразу в память считывать порцию данных из файла и в порции производить все замены, но так как мне дальше не обязательно держать в памяти именно строкой всю XML и для ещё большей оптимизации, решил делать запись в файл и его потом уже подавать процедуре чтения сообщения обмена.

7) Так же не забывайте убирать за собой, помогите сборщику мусора 1С, донесите свой мусор хотя бы до помойки:

Мусор = Неопределено;

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

Тем же, кто думает о своей реализации обмена данными через веб-сервис, я бы пожалуй посоветовал паковку в ZIP архив на сервере (можно даже в памяти это сделать, без записи на диск) и передавать двоичные данные, а на клиенте уже сохранить полученные двоичные данные на диск, а дальше можно использовать типовой механизм.

Выражаю благодарность автору обработки, которая сделала сказку - былью!
Если у вас есть лишние помидоры и яйца, то вспомните о голодающих ;)

PS: Прошу обратить внимание на то, что данная публикация, получает строку, помещенную в хранилище значение, если вы хотите таким образов получать другие типы данных помещенные в хранилище значение, вам явно придется вооружится напильником, но нет ничего не возможного!

PS: Так же надо учитывать, что данный способ медленней чем штатный способ получения значения! Обратите так же внимание, тестировать обработку лучше в файловой базе или хотя бы на 32-х битном сервере 1С, где есть техническое ограничение на потребляемую память. На 64-х битном сервере 1С, даже очень большие данные сможет получить. Да, обработка не демонстрирует проблему, а демонстрирует решение.

ХранилищеЗначения ХранилищеЗначения.Получить(); Вылетает

См. также

SALE! 20%

Перенос данных из УПП 1.3 в ERP 2 / УТ 11 / КА 2. Переносятся документы, справочная информация и остатки

Обмен между базами 1C Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос документов, начальных остатков и справочной информации из УПП 1.3 в ERP 2 | из УПП 1.3 в УТ 11 | из УПП в КА 2 | Правила конвертации (КД 2) в продаже с 2015 года, постоянно работаем над их развитием | Более 360 предприятий выполнили переход с использованием этого продукта! | Сэкономьте время - используйте готовое решение для перехода! | Позволяет перенести из УПП 1.3 в ERP / УТ 11 / КА 2 всю возможную информацию | В переносе есть фильтр по организации и множество других опциональных параметров выгрузки | Есть несколько алгоритмов выгрузки остатков на выбор

45650 36520 руб.

04.08.2015    159665    363    267    

345

SALE! 15%

[ED3] Обмен для ERP 2.5, КА 2.5, УТ 11.5 БП 3.0, Розница, УНФ и других с EnterpriseData (универсальный формат обмена), правила обмена

Обмен между базами 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

25080 22572 руб.

12.06.2017    134919    722    291    

388

SALE! 20%

Перенос данных из ERP 2 / КА 2 / УТ 11 в БП 3.0. Переносятся документы, начальные остатки и справочники

Обмен между базами 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | В продаже с 2019г. | Воспользовались более 176 предприятий! | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой, обращайтесь!

34650 27720 руб.

15.04.2019    68413    178    138    

111

SALE! 20%

Перенос данных из ERP 2 / КА 2 в ЗУП 3. Переносятся остатки, документы и справочники

Обмен между базами 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Воспользовались более 79 предприятий! | Предлагаем приобрести готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | В продаже с 2020г. | Оперативно обновляем правила до актуальных релизов 1С | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

43450 34760 руб.

03.12.2020    34167    80    58    

78

SALE! 10%

Перенос данных из УТ 10.3 в УТ 11.5. Переносятся документы (обороты за период), справочная информация и остатки

Обмен между базами 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 1С:Управление торговлей 11 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.87.x) и УТ 11.5 (11.5.16.x).

28000 25200 руб.

23.07.2020    46283    196    64    

157

SALE! 10%

Перенос данных из БП 3.0 в УТ 11 / КА 2 / ERP 2. Переносятся начальные остатки, документы и справочники

Обмен между базами 1C Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

В продаже с 2014г. | Воспользовались более 122 предприятий! | Перенос данных из БП 3.0 в УТ 11 | из БП 3.0 в КА 2 | из БП 3.0 в ERP | Сэкономьте свое время - используйте готовое решение для перехода! | Постоянно работаем над развитием переноса данных | Обновляем на новые релизы 1С | Есть фильтр выгрузки по организациям | Переносятся начальные остатки на выбранную дату, документы за период времени и вся возможная справочная информация | Перенос сделан на технологии КД 2 (правила конвертации данных)

50722 45650 руб.

31.10.2014    231389    124    327    

295

Перенос данных из Парус 10 в ЗГУ ред.3

Внешние источники данных Кадровый учет Файловый обмен (TXT, XML, DBF), FTP Обмен между базами 1C Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 10 учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

60000 руб.

05.10.2022    9205    9    8    

10

SALE! 10%

Перенос данных из УПП 1.3 в БП 3.0. Переносятся документы (обороты за период), справочная информация и остатки

Обмен между базами 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.223.x) и БП 3.0 (3.0.149.x). Правила подходят для версии ПРОФ и КОРП.

28000 25200 руб.

15.12.2021    20234    132    38    

90
Оставьте свое сообщение