Сжатие потока GZip с Delphi (опционально с tar) - PullRequest
0 голосов
/ 15 октября 2018

Я искал и искал по часам, чтобы создать действительный файл .tar.gz с использованием потоков в Delphi 10.

Мне удалось решить часть tarball, используя LibTar , который работаетну.

После некоторых поисков я также нашел примеры для распаковки данных gzip, используя System.ZLib.Секрет кроется в параметре WindowBits:

// 31 bit wide window = gzip only mode
DecompStream:= TZDecompressionStream.Create(SourceStream, 15 + 16);
TarStream:= TTarArchive.Create(DecompStream);
TarStream.Reset;
while TarStream.FindNext(DirRec) do {...} TarStream.ReadFile(TargetStream);

Отлично!Но действительно ли возможно, что System.ZLib способен распаковать gzip (я полагаю, просто игнорируя заголовок gzip этим +16?), Но не может создать такой заголовок сам по себе?Что бы я ни пытался, я получаю только файл, который не может быть открыт 7zip или WinRar, потому что заголовок отсутствует.

Может быть, он просто не может работать, потому что заголовок gzip содержит контрольную сумму, поэтому это невозможнонаписать заголовок, не зная следующих данных.Как это решить?Изменить: это неправильно, см. Комментарии: crc32 находится в трейлере.

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

1 Ответ

0 голосов
/ 15 октября 2018

Секрет кроется в параметре WindowBits - звучит знакомо?:)

Хотите верьте, хотите нет, но сжатие в gzip работает точно так же!Я не смог найти это нигде с помощью Google или в документации / справке Embarcadero.Но взгляните на этот комментарий в System.ZLib источнике Delphi Tokyo:

Добавьте 16 к windowBits, чтобы написать простой заголовок gzip и трейлер вокруг сжатых данных вместо оболочки zlib.Заголовок gzip не будет иметь ни имени файла, ни дополнительных данных, ни комментариев, ни времени изменения (установленного в ноль), ни заголовка crc, а операционная система будет установлена ​​в 255 (неизвестно).

Работает:

TargetStream:= TFileStream.Create(TargetFilename, fmCreate);
CompressStream:= TZCompressionStream.Create(TargetStream, zcDefault, 15 + 16);
TarStream:= TTarWriter.Create(CompressStream);
TarStream.AddStream(SourceStream1, SourceFilename1, Now);
TarStream.AddString(SourceString2, SourceFilename2, Now);
...