Форум: "Основная";
Текущий архив: 2008.02.10;
Скачать: [xml.tar.bz2];
ВнизПомогите распаковать gzip Найти похожие ветки
← →
Вопрошающий (2007-10-28 02:00) [0]нужно распаковать строку полученную при загрузке по хттп контента сжатого гзипом.
долго пытался что-то найти в поисковиках, но безуспешно.
пытался использовать функцию для распаковки строки сжатой zlib:
[code]
uses zlib;
...
function Unzlib(inpStr:string):string;
var
OutBuf: Pointer;
OutBytes: Integer;
outstream:TStringStream;
begin
OutStream:=TStringStream.create("");
OutBuf := nil;
try
try
DecompressBuf(pointer(InpStr), length(InpStr), 0, OutBuf, OutBytes);
outStream.Write(OutBuf^, OutBytes);
finally
if OutBuf <> nil then FreeMem(OutBuf);
end;
outStream.Position := 0;
Result:=outstream.DataString;
finally
OutStream.Free;
end;
end;
[/code]
предварительно обрезавши первые 10 байт (сигнатура гзип), и добавивши 2 байта (сигнатура zlib), а также обрезавши последние 8 байт (CRC32+ISIZE) (RFC1952)
Но все равно не могу распаковать строку.
Возможно это из-за того что в zlib после самого сжатого потока должно быть 4 байта, где используется не CRC32, а ADLER32 (RFC1950). Но его естественно я никаким образом не смогу получить.
Может кто-нить подскажет, как все-таки распаковать данные, сжатые gzip, не используя сторонних компонентов?
Тем более что в WIN уже имеется библиотека gzip.dll, неплохо было бы ее задействовать, но вот ее описание не могу нигде найти.
← →
Dimaxx © (2007-10-28 10:46) [1]
> вот ее описание не могу нигде найти
Плохо искал - погугли "gzip.dll+delphi" - выдаст море ссылок. Первые же 2-3 дают ответ.
← →
Вопрошающий (2007-10-28 18:21) [2]
> выдаст море ссылок.
ссылок-то море, но вот толку от них никакого...
Причем большая часть ссылок - это чьи-то аналогичные вопросы, причем с такими ответами как Ваш... Прям рекурсия какая-то... :-)
только на Королевстве нашел целую кучу подобных вопросов с ответами, заключающими в себе перенаправление куда подальше, в т.ч. гугль и т.п.
Ну нашел я один пример на сях. Но честно говоря, я так и не понял его. Да и что-то он мне доверия не внушает.
← →
Slym © (2007-10-29 06:10) [3]FastReport\Source\frxGZip.pas
← →
Slym © (2007-10-29 06:11) [4]в 10Indy тоже есть GZip декомпресор
← →
homm © (2007-10-29 06:16) [5]> [0] Вопрошающий (28.10.07 02:00)
> пытался использовать функцию для распаковки строки сжатой
> zlib:
> Но все равно не могу распаковать строку.
А должен был смочь?
← →
Slym © (2007-10-29 08:49) [6]Вопрошающий (28.10.07 2:00)
предварительно обрезавши первые 10 байт (сигнатура гзип)
Минимум 10 байт, на этом заголовок не кончается, из этих 10 байт выдергивается наличие доп заголовков/опций и их тоже нужно "вырезать"
← →
Вопрошающий (2007-10-29 18:23) [7]
> Минимум 10 байт, на этом заголовок не кончается, из этих
> 10 байт выдергивается наличие доп заголовков/опций и их
> тоже нужно "вырезать"
Я исходил из того что там должен быть именно минимум...
Это контент переданный хттп-сервером, только пожатый гзипом для экономии трафика... И вроде в этих 10 байтах не было флагов присутствия дополнительных заголовков/опций.
> homm © (29.10.07 06:16) [5]
> > [0] Вопрошающий (28.10.07 02:00)
> > пытался использовать функцию для распаковки строки сжатой
>
> > zlib:
> > Но все равно не могу распаковать строку.
>
> А должен был смочь?
Ну не знаю. Теоретически в гзипе используется метод сжатия zlib, поэтому я предположил, что должно сработать.
В инете находил шаманский метод по превращению данных сжатых zlib в gzip.
Там предлагается обрезать первых 2 байта (сигнатура zlib), вставивши вместо них 10 байтов сигнатуры gzip. Правда там имелся небольшой прокол связанный с контрольной суммой. Но автор написал, что это не особо важно, так как при распаковке такого гзип-файла стандартными средствами архиватор ругнется, но тем не менее распакует...
> Slym © (29.10.07 06:11) [4]
> в 10Indy тоже есть GZip декомпресор
Хм. Спасибо за подсказку... Поищу...
Кстати в стандартной поставке с 7 Дельфи какой Инди идет?
← →
Дмитрий Белькевич © (2007-10-30 02:20) [8]В Jedi: TJclGZIPDecompressionStream. Работает без проблем.
В 7-ке стандартной идут 9-е либы. Только старые.
← →
Вопрошающий (2007-10-30 16:45) [9]
> В Jedi: TJclGZIPDecompressionStream. Работает без проблем.
Я понимаю что гугль рулит, но все-таки огромнейшая просьба дать ссылку...
Так как в наше время как найти не трудно, трудно скачать...
← →
Вопрошающий (2007-10-31 06:16) [10]
> В Jedi: TJclGZIPDecompressionStream. Работает без проблем.
Скачал. Поробовал. Но проблемы все-таки есть...
Все вроде нормально расжимает, но страшно ругается при попытке обращения к свойству SIZE (выдает что "seek is not an supported operation").
и я уже не знаю как мне человеческим образом узнать размер распакованных данных...
← →
Вопрошающий (2007-10-31 06:30) [11]А при обращении к OriginalDataSize вылетает с "Stream read error"
← →
Slym © (2007-10-31 06:39) [12]Вопрошающий (31.10.07 6:16) [10]
seek is not an supported operation
сначала разожми, потом спрашивай размер... т.к. изначально размер без распаковки не известен
← →
Вопрошающий (2007-10-31 14:47) [13]
> сначала разожми, потом спрашивай размер... т.к. изначально
> размер без распаковки не известен
Хм... Вобщем пишу так:
function GZipStringDecompress(InputString:string):string;
var
SourceStream:TStringStream;
begin
SourceStream:=TStringStream.Create(InputString);
try
with TJclGZIPDecompressionStream.Create(SourceStream) do
try
SetString(result,nil,Size);
Read(Pointer(result)^, Size);
finally
Free;
end;
finally
SourceStream.Free;
end;
end;
подскажите плиз что тут нужно изменить/добавить...
← →
Вопрошающий (2007-10-31 14:53) [14]Кстати, при выполнении:
> Read(Pointer(result)^, Size);
если я вместо SIZE указываю каку-ю нить константу заведомо меньшую того кол-ва данных, которое было сжато, то получаю кусок нужных данных, т.е. уже разжатых... Но вот проблема в определении их длины...
← →
Вопрошающий (2007-10-31 17:12) [15]Вот нашел в гугле:
http://www.delphipraxis.net/topic109876.html
У человека такая же проблема...
Правда не могу понять что ему там написали, ибо язык не понятный. на немецкий смахивает... Но я его не знаю...
← →
Virgo_Style © (2007-10-31 19:17) [16]Первый пишет, что TStream - абстрактный предок и его использовать нельзя, что пишет второй - я перевести не могу, жди знатоков)
← →
Вопрошающий (2007-10-31 20:08) [17]Насчет первого я понял, что он обратил внимание на TStream, и поэтому, хоть он и правильно заметил, тем не менее его ответ не относится к существу вопроса.
Интерестно все-таки насколько результативен второй ответ?
← →
Virgo_Style © (2007-10-31 22:45) [18]Попытался вникнуть. М-да-а-а... давно я не брал в руки шашек...
Ansonsten wart mal ab. Gerade wird in der JCL an JclCompression gebaut.
Иначе были далеко однажды. Как раз строится в JCL в JclCompression.
(c) Prompt.
М-да.
Первое предложение мне больше кажется похожим на "Погоди-ка" или "Или подожди". Не пойму, это фигура речи или рекомендация по теме.
Вторая фраза вроде похожа на "Именно так устроен в JCL [юнит] JCLCompression", если так, то первая фраза - именно рекомендация.
p.s. Вот же делать мне нечего...
Жаль, слишком давно я работал с ZLib, уже не помню деталей, а ведь была подобная проблема...
Минуточку. > обрезавши последние 8 байт (CRC32+ISIZE)
ISize - это не в нашу тему?
Или еще мысль - нельзя ли разжимать постепенно, проверяя при этом position в сжатом потоке?
На этом я откланиваюсь, бо результаты ночных раздумий по утрам читать обычно или странно, или стыдно =)
← →
Вопрошающий (2007-11-01 00:58) [19]
> ISize - это не в нашу тему?
Хм. Как-то я сразу до этого не додумался... получается что это уже один из вариантов решения вопроса... только вот он как-то выглядит череззаднепроходно... Но за неимением других вариантов возможно придется именно его и использовать.
← →
Вопрошающий (2007-11-01 03:16) [20]Вобщем путем предварительного определения размера данных путем вырезания последних 4-х байт из исходных данных получилось расжать гзип
разжимается нормально...
Но при попытке написать все это более менее прилично выяснилось что метод seek почему-то не работает во всех наследниках TStream, в частности даже в TStringStream... Вобщем какие-то странные вещи...пока не могу понять с чем это связано...
← →
Slym © (2007-11-01 04:23) [21]Вопрошающий (31.10.07 14:47) [13]
function GZipStringDecompress(const InputString:string):string;
var
Source,Dest:TStringStream;
Buf:array[byte] of byte;
r:integer;
begin
Dest:=TStringStream.Create("");
try
Source:=TStringStream.Create(InputString);
try
with TJclGZIPDecompressionStream.Create(Source) do
try
while true do
begin
r:=Read(Buf,SizeOf(Buf));
if r<=0 then Break;
Dest.WriteBuffer(Buf,r);
end;
finally
Free;
end;
finally
Source.Free;
end;
result:=Dest.DataString;
finally
Dest.Free;
end;
end;
← →
Вопрошающий (2007-11-01 18:39) [22]
> while true do
> begin
> r:=Read(Buf,SizeOf(Buf));
> if r<=0 then Break;
> Dest.WriteBuffer(Buf,r);
> end;
Хм... Смысл мне не особо нравится... Но выглядит прилично... Да и работает...
Вобщем беру на вооружение этот вариант.
Спасибо!
← →
SuperHacker (2007-11-01 19:42) [23]
> нужно распаковать строку полученную при загрузке по хттп
> контента сжатого гзипом.
Я тоже долго с этим мучался, но потом решил проблему, используя zlib:
delete(s,1,pos(#13#10#13#10,s)+3);
s2:=GZDecompressStr(s);
В s лежит то, что сервер прислал, в s2 - раскодированный HTML.
В uses надо добавить ZlibExGz.
← →
SuperHacker (2007-11-01 20:29) [24]Забыл дописать: вышеуказанный юнит для Delphi я взял здесь: http://www.base2ti.com/zlib.htm
← →
Вопрошающий (2007-11-01 22:11) [25]
> delete(s,1,pos(#13#10#13#10,s)+3);
> s2:=GZDecompressStr(s);
#13#10#13#10 ...
Это разделитель заголовка ответа хттп сервера от самих данных...
к гзип оно отношения не имеет...
А за ссылку спасибо... Попробовал. Отлично работает...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.02.10;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.106 c