1С 8.3 Чтение GZip - Программист 1С Минск. Автоматизация бизнеса.

Перейти к контенту

1С 8.3 Чтение GZip

Перейти в основной раздел:
Структурированная copypaste с github.com для работа с GZip (форматом и утилитой сжатия и восстановления/декомпрессии файлов, использующая алгоритм Deflate).
Библиотека работы с утилитой GZip в 1С 8.3 (Основная функция):
Функция ПрочитатьGZip(СжатыеДанные) Экспорт

   РазмерПрефиксаGZip = 10;
   РазмерПостфиксаGZip = 8;

   Данные = Новый ЧтениеДанных(СжатыеДанные);
   Данные.Пропустить(РазмерПрефиксаGZip);
   РазмерСжатыхДанных = Данные.ИсходныйПоток().Размер() - РазмерПрефиксаGZip - РазмерПостфиксаGZip;

   ПотокZip = Новый ПотокВПамяти(ZipРазмерLFH() + РазмерСжатыхДанных + ZipРазмерDD() + ZipРазмерCDH() + ZipРазмерEOCD());
   ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);
   ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipLFH());
   Данные.КопироватьВ(ЗаписьДанных, РазмерСжатыхДанных);

   ЗаписьДанных.Закрыть();
   ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);

   CRC32 = Данные.ПрочитатьЦелое32();
   РазмерНесжатыхДанных = Данные.ПрочитатьЦелое32();
   Данные.Закрыть();

   ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
   ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipCDH(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
   ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipEOCD(РазмерСжатыхДанных));
   ЗаписьДанных.Закрыть();

   Возврат ПрочитатьZip(ПотокZip);

КонецФункции
Библиотека работы с утилитой GZip в 1С 8.3 (Вспомогательные функции):
Функция ПрочитатьZip(СжатыеДанные, ТекстОшибки = Неопределено)

    #Если МобильноеПриложениеСервер Тогда
       ВызватьИсключение(НСтр("ru = 'Работа с Zip-файлами в мобильной платформе не поддерживается'"));
    #Иначе
       Каталог = ПолучитьИмяВременногоФайла();
       ЧтениеZip = Новый ЧтениеZipФайла(СжатыеДанные);
       ИмяФайла = ЧтениеZip.Элементы[0].Имя;
       Попытка
           ЧтениеZip.Извлечь(ЧтениеZip.Элементы[0], Каталог, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
       Исключение
           // Игнорируем проверку целостности архива, просто читаем результат
           ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;
       ЧтениеZip.Закрыть();

       Результат = Новый ДвоичныеДанные(Каталог + ПолучитьРазделительПути() + ИмяФайла);
       УдалитьФайлы(Каталог);

       Возврат Результат;
    #КонецЕсли

КонецФункции

#Область СлужебныеСтруктурыZip
// Описание структур см. здесь https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

Функция ZipРазмерLFH()

   Возврат 34;

КонецФункции

Функция ZipРазмерDD()

   Возврат 16;

КонецФункции

Функция ZipРазмерCDH()

   Возврат 50;

КонецФункции

Функция ZipРазмерEOCD()

   Возврат 22;

КонецФункции

Функция ZipLFH()

   // Local file header
   Буфер = Новый БуферДвоичныхДанных(ZipРазмерLFH());
   Буфер.ЗаписатьЦелое32(0, 67324752); // signature 0x04034b50
   Буфер.ЗаписатьЦелое16(4, 20);       // version
   Буфер.ЗаписатьЦелое16(6, 10);       // bit flags
   Буфер.ЗаписатьЦелое16(8, 8);        // compression method
   Буфер.ЗаписатьЦелое16(10, 0);       // time
   Буфер.ЗаписатьЦелое16(12, 0);       // date
   Буфер.ЗаписатьЦелое32(14, 0);       // crc-32
   Буфер.ЗаписатьЦелое32(18, 0);       // compressed size
   Буфер.ЗаписатьЦелое32(22, 0);       // uncompressed size
   Буфер.ЗаписатьЦелое16(26, 4);       // filename legth - "data"
   Буфер.ЗаписатьЦелое16(28, 0);       // extra field length
   Буфер.Записать(30, ПолучитьБуферДвоичныхДанныхИзСтроки("data", "ascii", Ложь));

   Возврат Буфер;

КонецФункции

Функция ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных)

   // Data descriptor
   Буфер = Новый БуферДвоичныхДанных(ZipРазмерDD());
   Буфер.ЗаписатьЦелое32(0, 134695760);
   Буфер.ЗаписатьЦелое32(4, CRC32);
   Буфер.ЗаписатьЦелое32(8, РазмерСжатыхДанных);
   Буфер.ЗаписатьЦелое32(12, РазмерНесжатыхДанных);

   Возврат Буфер;

КонецФункции

Функция ZipCDH(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных)

   // Central directory header
   Буфер = Новый БуферДвоичныхДанных(ZipРазмерCDH());
   Буфер.ЗаписатьЦелое32(0, 33639248);              // signature 0x02014b50
   Буфер.ЗаписатьЦелое16(4, 798);                   // version made by
   Буфер.ЗаписатьЦелое16(6, 20);                    // version needed to extract
   Буфер.ЗаписатьЦелое16(8, 10);                    // bit flags
   Буфер.ЗаписатьЦелое16(10, 8);                    // compression method
   Буфер.ЗаписатьЦелое16(12, 0);                    // time
   Буфер.ЗаписатьЦелое16(14, 0);                    // date
   Буфер.ЗаписатьЦелое32(16, CRC32);                // crc-32
   Буфер.ЗаписатьЦелое32(20, РазмерСжатыхДанных);   // compressed size
   Буфер.ЗаписатьЦелое32(24, РазмерНесжатыхДанных); // uncompressed size
   Буфер.ЗаписатьЦелое16(28, 4);                    // file name length
   Буфер.ЗаписатьЦелое16(30, 0);                    // extra field length
   Буфер.ЗаписатьЦелое16(32, 0);                    // file comment length
   Буфер.ЗаписатьЦелое16(34, 0);                    // disk number start
   Буфер.ЗаписатьЦелое16(36, 0);                    // internal file attributes
   Буфер.ЗаписатьЦелое32(38, 2176057344);           // external file attributes
   Буфер.ЗаписатьЦелое32(42, 0);                    // relative offset of local header
   Буфер.Записать(46, ПолучитьБуферДвоичныхДанныхИзСтроки("data", "ascii", Ложь));

   Возврат Буфер;

КонецФункции

Функция ZipEOCD(РазмерСжатыхДанных)

   // End of central directory
   РазмерCDH = 50;
   Буфер = Новый БуферДвоичныхДанных(ZipРазмерEOCD());
   Буфер.ЗаписатьЦелое32(0, 101010256); // signature 0x06054b50
   Буфер.ЗаписатьЦелое16(4, 0); // number of this disk
   Буфер.ЗаписатьЦелое16(6, 0); // number of the disk with the start of the central directory
   Буфер.ЗаписатьЦелое16(8, 1); // total number of entries in the central directory on this disk
   Буфер.ЗаписатьЦелое16(10, 1); // total number of entries in the central directory
   Буфер.ЗаписатьЦелое32(12, РазмерCDH); // size of the central directory
   // offset of start of central directory with respect to the starting disk number
   Буфер.ЗаписатьЦелое32(16, ZipРазмерLFH() + РазмерСжатыхДанных + ZipРазмерDD());
   Буфер.ЗаписатьЦелое16(20, 0); // the starting disk number

   Возврат Буфер;

КонецФункции

#КонецОбласти

#Область СлужебныеСтруктурыGZip

// Описание структур см. здесь https://www.ietf.org/rfc/rfc1952.txt

Функция GZipРазмерHeader()

   Возврат 10;

КонецФункции

Функция GZipРазмерFooter()

   Возврат 8;

КонецФункции

Функция GZipHeader()

   Буфер = Новый БуферДвоичныхДанных(GZipРазмерHeader());
   Буфер[0] = 31;               // ID1 0x1f
   Буфер[1] = 139;              // ID2 0x8b
   Буфер[2] = 8;                // compression method (08 for DEFLATE)
   Буфер[3] = 0;                // header flags
   Буфер.ЗаписатьЦелое32(4, 0); // timestamp
   Буфер[8] = 0;                // compression flags
   Буфер[9] = 255;              // operating system ID

   Возврат Буфер;

КонецФункции

Функция GZipFooter(CRC32, РазмерИсходныхДанных)

   Буфер = Новый БуферДвоичныхДанных(GZipРазмерFooter());
   Буфер.ЗаписатьЦелое32(0, CRC32);
   Буфер.ЗаписатьЦелое32(4, РазмерИсходныхДанных);

   Возврат Буфер;

КонецФункции

#КонецОбласти
0
комментарии
____________________
Copyright©, «Программист 1С в г.Минске», 21.12.2023
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник
Назад к содержимому