StreamDecompress

From SunFlurry wiki
Revision as of 08:43, 27 November 2023 by Admin (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  StreamCompress (Функции архивации)
Объект:Функции общего назначения
Статус разработки: Частичная реализация
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в строку, число, неверный аргумент, внешняя ошибка
Визуальность:Нет

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

Синтаксис

StreamDecompress(<Данные для распаковки (STRING,BUFFER)>,<Алгоритм (STRING)>="ZLIB",<Завершающий блок (INT)>=1,<Словарь распаковки или общий размер упакованного блока (INT,?)>):<Результат распаковки (STRING,BUFFER)>

Аргументы

  • <Данные для распаковки (STRING,BUFFER,TEXT)> - Функция поддерживает получение информации из строк или буферов. Строки должны иметь формат ANSI, иначе они будут перекодированы в него, что может стать причиной порчи данных.
  • <Алгоритм (STRING)> - (необязательный аргумент) Строка, задающая используемый алгоритм. Поддерживаются следующие алгоритмы:
    • ZLIB (по умолчанию): Распаковка будет происходить методом Inflate для данных, ранее упакованных Zlib. При использовании этого метода не требуется указывать полный размер упакованного файла до начала распаковки в аргументе <Словарь распаковки>.
    • GZIP или GZ: Распаковка будет происходить методом Inflate для данных, ранее упакованных Gzip. При использовании этого метода требуется указывать полный размер упакованного файла до начала распаковки в аргументе <Словарь распаковки> (см. пример).
  • <Завершающий блок (INT)> - (необязательный аргумент) Указывает на то, что это последний блок в серии блоков для распаковки. При распаковке большого блока частями важно, чтобы вызов с аргументом равным 1 был последним и единственным и больше вызовов с тем же самым словарем не производилось.
  • <Словарь упаковки или общий размер упакованного блока> - (необязательный аргумент) (возможен аргумент-переменная (ByRef)) При распаковке большого блока частями необходимо передать в этот аргумент переменную, которая в начале упаковки будет равна размеру упакованного файла (для метода Gzip) или нулю (для метода Zlib). Эта переменная будет хранить промежуточное состояние распаковки (чаще всего буфер). После выполнения последней операции распаковки (Завершающий блок равен 1), внутренние ресурсы, требуемые на распаковку, освобождаются, и переменная будет хранить неопределенное значение (чаще всего буфер с бесполезной информацией) до того, как она будет удалена из системы.

Возвращаемое значение

В зависимости от аргумента <Данные для распаковки>, функция возвращает:

  • <Данные для распаковки> являются строкой: результат распаковки переменного блока данных в виде строки ANSI (поэтому предпочтительно упаковывать строки UTF-16, предварительно перекодировав их в UTF-8)
  • <Данные для распаковки> являются буфером: результат распаковки переменного блока данных в виде буфера.

Примеры

//Загрузим файл в строку
сФайл:=FileToString("C:\ТестовыйФайл.txt");

//Упакуем строку сФайл с помощью алгоритма GZip частями по 1024 байта
РазмерБлока:=1024;
Словарь:=0;
сРезультат:="";
j:=0;
For i:=1 To Length(сФайл) div РазмерБлока Do
  j:=j+РазмерБлока;
  сРезультат:=сРезультат+StreamCompress(Mid(сФайл,(i-1)*РазмерБлока+1,РазмерБлока),"GZ",6,0,Словарь);
EndDo;
//Упакуем последний блок меньше 1024 байт (возможен пустой блок)
сРезультат:=сРезультат+StreamCompress(Right(сФайл,Length(сФайл)-j),"GZ",6,1,Словарь);

//Сохраним упакованный блок в виде файла
StringToFile(сРезультат,"C:\ТестовыйФайл.gz");

//Распакуем блок сРезультат с помощью алгоритма GZip частями по 1024 байта
//Для GZip необходимо также указать общий размер упакованного блока в переменной Словарь при первом вызове
РазмерБлока:=1024;
Словарь:=Length(сРезультат);
сФайл2:="";
j:=0;
For i:=1 To Length(сРезультат) div РазмерБлока Do
  j:=j+РазмерБлока;
  сФайл2:=сФайл2+StreamDecompress(Mid(сРезультат,(i-1)*РазмерБлока+1,РазмерБлока),"GZ",0,Словарь);
EndDo;
//Распакуем последний блок меньше 1024 байт (возможен пустой блок)
сФайл2:=сФайл2+StreamDecompress(Right(сРезультат,Length(сРезультат)-j),"GZ",1,Словарь);

//Сравним сФайл и сФайл2
If сФайл<>сФайл2 Then
  Message("Результаты не совпадают!","!");
Else
  Message("Результаты совпадают!","I");
EndIf;