Ситуация — есть данные в файле, часть из них запакована в gzip формате. Но когда эти данные спихивались в кучу у них у всех отрезался заголовок, который, как я понимаю, должен быть стандартным. Если был хвост, то он, отрезан тоже. Вопрос можно чем-нибудь распаковать такие данные не делая себе кучу головной боли. Код на C с использованием zlib для этого есть, но под C# его переводить — довольно проблемно. Смотрел в сторону DotNetZip, но так и не понял можно ли так сделать.
Т.е. фактически есть буфер byte[] и его надо раззиповать, размер после распаковки есть.
P_A>System.IO.Compression.GZipStream ?
Не проходит — непонятно что именно ему подсовывать в качестве заголовка. Без него ругается на magic number, если пытаться подсунуть то, что я видел как стандартный — то не опознает тип блока.
Здравствуйте, Arnx, Вы писали:
>Код на C с использованием zlib для этого есть, A>Т.е. фактически есть буфер byte[] и его надо раззиповать, размер после распаковки есть.
Ну если zlib работает, то можно взять zlib.net, наверное
Здравствуйте, Arnx, Вы писали:
A>Ситуация — есть данные в файле, часть из них запакована в gzip формате. Но когда эти данные спихивались в кучу у них у всех отрезался заголовок, который, как я понимаю, должен быть стандартным. Если был хвост, то он, отрезан тоже. Вопрос можно чем-нибудь распаковать такие данные не делая себе кучу головной боли. Код на C с использованием zlib для этого есть, но под C# его переводить — довольно проблемно. Смотрел в сторону DotNetZip, но так и не понял можно ли так сделать. A>Т.е. фактически есть буфер byte[] и его надо раззиповать, размер после распаковки есть.
P_A>Ну если zlib работает, то можно взять zlib.net, наверное
Спасибо, с ней таки получилось, хотя мапил сишные примеры в C# я довольно долго.
Потом наткнулся на похожую библиотеку, где были очень похожие вызовы с нормально описанными значениями входных и выходных параметров.
В итоге вышло просто, что-то вроде
Здравствуйте, Arnx, Вы писали:
P_A>>Ну если zlib работает, то можно взять zlib.net, наверное A>Спасибо, с ней таки получилось, хотя мапил сишные примеры в C# я довольно долго. A>Потом наткнулся на похожую библиотеку, где были очень похожие вызовы с нормально описанными значениями входных и выходных параметров. A>В итоге вышло просто, что-то вроде A>
A>zlib.ZStream stream = new zlib.ZStream();
A>stream.next_in = buf32k;
A>stream.avail_in = buf32k.Length;
A>initRes = stream.inflateInit(); ///0 - good
A>stream.next_out = outBuffer;
A>stream.avail_out = (int)entity.RealSize;
A>..
A>rc = stream.inflate(zlib.zlibConst.Z_NO_FLUSH);
A>..
A>stream.inflateEnd();
A>
Здравствуйте, Arnx, Вы писали:
A>Ситуация — есть данные в файле, часть из них запакована в gzip формате. Но когда эти данные спихивались в кучу у них у всех отрезался заголовок, который, как я понимаю, должен быть стандартным. Если был хвост, то он, отрезан тоже. Вопрос можно чем-нибудь распаковать такие данные не делая себе кучу головной боли. Код на C с использованием zlib для этого есть, но под C# его переводить — довольно проблемно.
Оформить код на С в виде DLL с одной функцией и вызвать через P/Invoke ?
Здравствуйте, Arnx, Вы писали:
A>Ситуация — есть данные в файле, часть из них запакована в gzip формате. Но когда эти данные спихивались в кучу у них у всех отрезался заголовок, который, как я понимаю, должен быть стандартным. Если был хвост, то он, отрезан тоже. Вопрос можно чем-нибудь распаковать такие данные не делая себе кучу головной боли. Код на C с использованием zlib для этого есть, но под C# его переводить — довольно проблемно. Смотрел в сторону DotNetZip, но так и не понял можно ли так сделать. A>Т.е. фактически есть буфер byte[] и его надо раззиповать, размер после распаковки есть.
Если вы точно знаете, что данные запакованы gzip-ом, то в .NET есть для этого спец. класс DeflateStream
// buf - Это входной байтовый буфер без "заголовка" и "хвоста" с запакованными данными
// bw - Это выходной поток, куда вы распаковываете ( у меня это был BinaryWriter )using( MemoryStream inStream = new MemoryStream( buf ) )
using( DeflateStream ds = new DeflateStream( inStream, CompressionMode.Decompress ) )
{
ds.CopyTo( bw.BaseStream );
}
Здравствуйте, Arnx, Вы писали:
A>Ситуация — есть данные в файле, часть из них запакована в gzip формате. Но когда эти данные спихивались в кучу у них у всех отрезался заголовок, который, как я понимаю, должен быть стандартным. Если был хвост, то он, отрезан тоже. Вопрос можно чем-нибудь распаковать такие данные не делая себе кучу головной боли. Код на C с использованием zlib для этого есть, но под C# его переводить — довольно проблемно. Смотрел в сторону DotNetZip, но так и не понял можно ли так сделать. A>Т.е. фактически есть буфер byte[] и его надо раззиповать, размер после распаковки есть.
Если все так, как Вы описали, то класс System.Io.Compression.DeflateStream должен подойти.
Приведу маленькая справку, если кому интересно.
В основе сжатия Zlib и GZip лежит алгоритм Deflate.
Zlib добавляет 2 байта заголовков в начало Deflate-потока и 4 байта контрольной суммы (Adler32) в конец.
У Gzip заголовки другие (обычно 10 или немного больше), а в конце потока CRC32 и 4 байта длины.
Вот и вся разница.
С потоком данных, который сжат любым из этих трех методов, можно работать как с "сырым" Deflate,
если правильно пропустить заголовки и хвост.
Deflate в своей работе использует так называемое "скользящее окно" и для правильного разжатия
Deflate-потока декомпрессор должен иметь размер окна, равный или больший тому, который был
задан при компрессии, иначе получим ошибку. Это единственная, пожалуй, тонкость, которую следует знать.
В библиотеке Zlib, например, размер окна может задаваться явно при создании декомпрессора.