Здравствуйте, SeLo, Вы писали:
S>>Flush() это метод стрима. Идеология правильная. Сам создавай входной стрим, а уж как ты его будешь запонять это твои проблемы. Для сжатия данных нужен входящий поток и не более. Он сам будет брать данные нужными для него порциями.
SL>и...? или вы меня недопоняли, или я. какими порциями? где это регулируется? почему результыты компресси такие разные? понятно что идеалогия привильная, но вот класс этот GZip как-то криво реализованн
Прошу прощения. Замкнуло. Обычно (для компресси декомпрессии) На вход подается стрим, а не массив байт (что более логично). В этом его и не доделанность.
и солнце б утром не вставало, когда бы не было меня
Интересно а как с такой идеологией чтения части компрессированных данных? В лучшем случае контрольная сумма не сойдется. Недавно случай с 7 zip был. Данные были заархивированы по частям. Так вот если часть была не полной, или вообще отсутствовала, никаких предупреждений на этот счет не было. Ну а вообще при компресии чем больше данных подаешь тем больше коэффициент компресси и получишь (там как в алгоритме LZRW плавающее окно испльзуется), и никаких предварительных накоплений не происходит. Лучше было добавить два метода СжатьПоток, и РазжатьПоток, все таки объемы, могут быть большими
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали: S>Интересно а как с такой идеологией чтения части компрессированных данных?
Никак. Чтение всегда восстанавливает исходный поток. S>Ну а вообще при компресии чем больше данных подаешь тем больше коэффициент компресси и получишь (там как в алгоритме LZRW плавающее окно испльзуется), и никаких предварительных накоплений не происходит.
Вот это мне не вполне понятно. Я в компрессии слабо разбираюсь, но мне казалось, что потоковые алгоритмы на то и потоковые, что должны работать независимо от того, какими блоками подаются входные данные. S>Лучше было добавить два метода СжатьПоток, и РазжатьПоток, все таки объемы, могут быть большими
И как бы это работало? Поток — штука пассивная. Ты заталкиваешь в него данные, а не другой поток. Представь себе, что ты хочешь передавать пожатые данные по сети, при этом не делая 100% буферизацию. Ты заворачиваешь исходящий поток в GzipStream и запихиваешь в него данные по мере готовности. Эта готовность может происходить блоками произвольного объема. А в итоге получаешь какую-то нездоровую зависимость непонятно от чего.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Посмотрел DeflateStream там в Dispose(bool disposing)
вызывается deflater.Finish(this.buffer) который и заканчивает запись исходного кодировщика.
Но !!! сжимать он начинает сразу, поэтому чем больше ты подашь на вход данных тем больше сожмет, т.к. используется плавающее окно а в выходной файл записывается смещение этого окна и длина строки, поэтому чем дленее строка и есть ее значение в плавающем окне тем коэффициент сжатия больше.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Sinclair, Вы писали:
S>Вот это мне не вполне понятно. Я в компрессии слабо разбираюсь, но мне казалось, что потоковые алгоритмы на то и потоковые, что должны работать независимо от того, какими блоками подаются входные данные.
Вообще говоря, в сжатии по Хаффмэну очень важно, что выбирается за единицу алфавита и насколько удачно делается этот выбор. Из общих соображений понятно, что вполне возможны варианты, когда выбор единицы алфавита делается исходя из куска доступных данных, что неразрывно связано с размером буфера.
Здравствуйте, Кэр, Вы писали:
Кэр>Вообще говоря, в сжатии по Хаффмэну очень важно, что выбирается за единицу алфавита и насколько удачно делается этот выбор.
Только в GZip используется не сжатие по Хаффману.
Кэр> Из общих соображений понятно, что вполне возможны варианты, когда выбор единицы алфавита делается исходя из куска доступных данных, что неразрывно связано с размером буфера.
Попробуй поинтересоваться как работает тот же LZW.
... <<RSDN@Home 1.2.0 alpha 4 rev. 1074 on Windows Vista 6.0.6001.65536>>
Здравствуйте, AndrewVK, Вы писали:
Кэр>>Вообще говоря, в сжатии по Хаффмэну очень важно, что выбирается за единицу алфавита и насколько удачно делается этот выбор. AVK>Только в GZip используется не сжатие по Хаффману.
Это был ответ на общую фразу по потоковым алгоритмам сжатия, цитата была приведена.
Кэр>> Из общих соображений понятно, что вполне возможны варианты, когда выбор единицы алфавита делается исходя из куска доступных данных, что неразрывно связано с размером буфера. AVK>Попробуй поинтересоваться как работает тот же LZW.
Всенепременно. Что конкретно смотреть в этом алгоритме?
Здравствуйте, _Morpheus_, Вы писали:
_M_>Здравствуйте, Serginio1, Вы писали:
S>>Посмотрел DeflateStream там в Dispose(bool disposing)
_M_>то что жмет сразу после записи, это хорошо, плохо вот именно с DeflateStream, см. тут
(Нужно же дать работу сторонним разработчика )
Жмет в методе write сразу поданный в него буфер.
Ну когда подают по одному байту, то не есть хорошо. Здесь как раз хофман хорошо подходит.
Но LZRW и чем он большую общую последовательность найдет в плавающем окне тем лучше для коэффициента сжатия.
Проще одним блоком все подать. А лучше из готового стрима в стрим.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, SeLo, Вы писали:
SL>Сжатие данных не работает так как хотелось бы:
и действительно, не работает. давненько хотел написать, да все рука не поднималась по-аглицки...
public static byte[] CompressData(byte[] data) {
if(data != null) {
using(MemoryStream ms = new MemoryStream()) {
using(GZipStream deflater = new GZipStream(ms, CompressionMode.Compress, true)) {
deflater.Write(data, 0, data.Length);
}
return ms.ToArray();
}
}
else {
return null;
}
}
[Test/*, Ignore("CompressionUtils.CompressData compresses 1Mb of data into 1.6Mb!!! of compressed data")*/]
public void TestCompressionRate() {
byte[] nonCompressableSource = new byte[1024 * 1024];
System.Random rnd = new Random();
rnd.NextBytes(nonCompressableSource);
byte[] compressedNonCompressableSource = CompressionUtils.CompressData(nonCompressableSource);
Assert.IsTrue(compressedNonCompressableSource.Length < nonCompressableSource.Length,
"{0} : {1}", compressedNonCompressableSource.Length, nonCompressableSource.Length);
}
-----------------
compressedNonCompressableSource.Length 1610496 int
nonCompressableSource.Length 1048576 int
-----------------
ну и кто мне объяснит, что я делаю не так??? почему и 1Мб получается 1.6Мб ????
поток в результате получается вполне читабельный для распаковщиков (pkunzip), но те же самые упаковщики (pkzip) делают из этого потока 1 049 004 bytes.
почему?
Здравствуйте, Dan Ignatov, Вы писали:
DI>Здравствуйте, SeLo, Вы писали:
SL>>Сжатие данных не работает так как хотелось бы:
DI>и действительно, не работает. давненько хотел написать, да все рука не поднималась по-аглицки...
Здравствуйте, Dan Ignatov, Вы писали: DI>ну и кто мне объяснит, что я делаю не так??? почему и 1Мб получается 1.6Мб ????
Потому что случайные данные плохо поддаются сжатию. DI>поток в результате получается вполне читабельный для распаковщиков (pkunzip), но те же самые упаковщики (pkzip) делают из этого потока 1 049 004 bytes. DI>почему?
Потому, что умные упаковщики, видя такую хрень, переключаются на метод компрессии "store".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Не читайте книги в которых стримы и IDisposable используют без оператора using.
Re[3]: Сжатие данных GZipStream
От:
Аноним
Дата:
10.07.08 12:28
Оценка:
Здравствуйте, Sinclair, Вы писали:
S>Потому что случайные данные плохо поддаются сжатию.
это-то как раз очевидно... S>Потому, что умные упаковщики, видя такую хрень, переключаются на метод компрессии "store".
хм.. не знал, что GZipStream не учитывает подобные данные...
спасибо.
Thanks,
Dan
Re[2]: Сжатие данных GZipStream
От:
Аноним
Дата:
20.07.08 09:03
Оценка:
A>Не читайте книги в которых стримы и IDisposable используют без оператора using.
А как быть с асинхронной моделью с функцией обратного вызова? использовования using — не панацея