1С 8.3 Чтение GZip
Данные > Примеры кода 1С > 1С 8.3 ZIP
Перейти в основной раздел:
Структурированная 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 = 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, РазмерИсходныхДанных);
Возврат Буфер;
КонецФункции
#КонецОбласти
#Если МобильноеПриложениеСервер Тогда
ВызватьИсключение(НСтр("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
комментарии
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник