Функция deflate zlib принимает параметр Z_FULL_FLUSH
в качестве аргумента, насколько мне известно, при выполнении полного сброса будет установлена точка полного сброса (0,0,0xFF,0xFF)
, последующие данные будут независимы от байтов, предшествующих этой точке, поэтому сжатие данные квазислучайно доступны. Я прочитал небольшой источник dictzip, он воспользовался этой функцией. чтобы реализовать произвольную доступность по частям, но при этом сохранить совместимость с gzip. Я хочу повторно реализовать компрессор/декомпрессор dictzip, используя функциональные возможности CLR. Декомпрессор (считыватель случайных частей) прост, я могу просто использовать DeflateStream для распаковки данных по частям без проблем, но что касается создания, есть огромное препятствие, API DeflateStream слишком высокоуровневый, кажется, что все детали дефляции скрыты, поэтому их нельзя использовать. Мне очень не нравится включать общую библиотеку C в мой проект C#, это делает кроссплатформенное развертывание очень болезненным и в первую очередь сводит на нет преимущества выбора кодирования на C#. И что я должен делать? Можно ли как-то обойти это препятствие, просто используя управляемый код? Предоставляет ли Mono оболочку более низкого уровня для zlib, чтобы я мог вызывать deflate с опцией полного сброса? Любой совет будет оценен!
--- >8 ---
Спасибо Марку Адлеру, который дал ответ. DotNetZip (в частности, Ionic.Zlib.DeflateStream) поддерживает именно ту функцию, о которой я просил. В следующем примере показано, как это работает:
Encoding u8 = Encoding.UTF8;
byte[] s1 = u8.GetBytes("the quick brown fox "),
s2 = u8.GetBytes("jumps over the lazy dog!");
var ms = new MemoryStream(100);
var deflator = new DeflateStream(ms, CompressionMode.Compress, true);
deflator.FlushMode = FlushType.Full;
deflator.Write(s1, 0, s1.Length);
deflator.Flush();
var pos = ms.Position;//remember the full flush point
deflator.Write(s2, 0, s2.Length);
deflator.Dispose();
var inflator = new DeflateStream(ms, CompressionMode.Decompress);
ms.Position = pos;
byte[] buf = new byte[100];
inflator.Read(buf, 0, s2.Length);
Console.WriteLine(u8.GetString(buf));//output: jumps over the lazy dog!