Оказалось, что если, как описанно в книге сбрасывать, по одному байту, по всей видимости сразу же компрессирует этот байт. В результате никакой компрессии 559 Кб -> 528 Kб. Я ожидал, что GZipStream накапилвает эти байты в каком-то буфере и потом после заполнения этого буфера, компресирует данные и затем передает их в FileStream. Если в GZipStream передавать куски байтов, то компрессия на порядок лучше . Вопрос: можно ли как-то контроллировать буфер (размер, время сброса данных — типа AutoFlush = False и т.д) или для нормальной компрессии возможна только запись сегметами (например по 100 байт)?
Здравствуйте, SeLo, Вы писали:
SL>Оказалось, что если, как описанно в книге сбрасывать, по одному байту, по всей видимости сразу же компрессирует этот байт.
У тебя в коде где-то ошибка. Никакой разницы, блоками какого размера оперировать, нет.
Попробуй сначала написать программу, которая работает. А потом уже тренироваться в коэффициентах сжатия.
Как минимум, все потоки нужно закрывать:
int blockSize = 1; // вот этим будешь играть, меняя размер блокаstring inFileName = @"c:\test.txt";
string outFileName = @"c:\test_Compres.txt";
byte[] buffer = new byte[blockSize];
using(FileStream sourceFile = File.OpenRead(inFileName))
using(FileStream destFile = File.Create(outFileName)))
using(GZipStream compStream = new GZipStream(destFile, CompressionMode.Compress))
{
int actualSize;
while ((actualSize = sourceFile.Read(buffer, 0, blockSize)>0)
compStream.Write(buffer, 0, actualSize);
}
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Сжатие данных GZipStream
От:
Аноним
Дата:
06.04.08 10:20
Оценка:
Здравствуйте, SeLo, Вы писали:
SL>поскипано SL>Я ожидал, что GZipStream накапилвает эти байты в каком-то буфере и ..... SL>поскипано
Обычно чтобы не предугадывать как и что будет работать — читают MSDN, в крайнем случае берут рефлектор и смотрят напрямую.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, SeLo, Вы писали:
SL>>// Мой вариант (тестовый, плз. без критики) SL>>byte[] byteArray = new byte[sourceFile.Length]; SL>>sourceFile.Read(byteArray, 0, (int)sourceFile.Length); SL>>compStream.Write(byteArray, 0, byteArray.Length); SL>>// 559 -> 13
AVK>Без критики не получится. Кто исходный поток в начало перематывать будет?
S>У тебя в коде где-то ошибка. Никакой разницы, блоками какого размера оперировать, нет.
Пример проверил: в точности как в книге, ошибок нет
S>int blockSize = 1; // вот этим будешь играть, меняя размер блока
Получается размер буфера все-таки влияет на коэффициент сжатия. Именно это мне и было интересно
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, SeLo, Вы писали:
SL>>поскипано SL>>Я ожидал, что GZipStream накапилвает эти байты в каком-то буфере и ..... SL>>поскипано А>Обычно чтобы не предугадывать как и что будет работать — читают MSDN, в крайнем случае берут рефлектор и смотрят напрямую.
Вот в MSDN говориться что WriteByte по сути вызывает метод Write, который (извиняюсь немецкий мне роднее):
Der verwendete Puffer ist ein interner Puffer. Der Schreibvorgang wird möglicherweise nicht unmittelbar ausgeführt, wird jedoch gepuffert, bis die Puffergröße erreicht ist oder bis die Flush-Methode oder die Close-Methode aufgerufen wird.
ЗДесь говориться, что есть внутренний буфер. Запись не будет непосредственно выполненна, а проверенно заполненн ли буфер. Также можно выписать данные методо Flush и Close.
Но какой размер буфера? и как на этот размер влиять?
Re[3]: Сжатие данных GZipStream
От:
Аноним
Дата:
06.04.08 10:49
Оценка:
Здравствуйте, SeLo, Вы писали:
SL>Вот в MSDN говориться что WriteByte по сути вызывает метод Write, который (извиняюсь немецкий мне роднее):
у GZipStream нет реализации ReadByte\WriteByte
ReadByte Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream. (Inherited from Stream.)
WriteByte Writes a byte to the current position in the stream and advances the position within the stream by one byte. (Inherited from Stream.)
SL>>Вот в MSDN говориться что WriteByte по сути вызывает метод Write, который (извиняюсь немецкий мне роднее):
А>у GZipStream нет реализации ReadByte\WriteByte
Если я не правильно выразился, то именно это я и имел ввиду. В Классе Stream эти методы создают массив с одним элементом и вызвают Read/Write
Здравствуйте, SeLo, Вы писали: S>>int blockSize = 1; // вот этим будешь играть, меняя размер блока SL>Получается размер буфера все-таки влияет на коэффициент сжатия. Именно это мне и было интересно
Охренеть дайте две. Ты прав, посыпаю голову пеплом. Век живи, век учись.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Сжатие данных GZipStream
От:
Аноним
Дата:
06.04.08 11:28
Оценка:
Здравствуйте, SeLo, Вы писали:
Вроде понял о чем речь
Это потоковый класс, соответсвенно сколько дашь, столько и сожмёт.
О чём и говорится в описании к классу:
The compression functionality in DeflateStream and GZipStream is exposed as a stream. Data is read in on a byte-by-byte basis, so it is not possible to perform multiple passes to determine the best method for compressing entire files or large blocks of data.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, SeLo, Вы писали:
А>Вроде понял о чем речь А>Это потоковый класс, соответсвенно сколько дашь, столько и сожмёт. А>О чём и говорится в описании к классу: А>
А>The compression functionality in DeflateStream and GZipStream is exposed as a stream. Data is read in on a byte-by-byte basis, so it is not possible to perform multiple passes to determine the best method for compressing entire files or large blocks of data.
Это описывает лишь суть алгоритма сжатия (как и распаковки), который не предусматривает многократного прохода по данным. Данный сжимаются налету, и потому вписываются в идиалогию потоков (Stream), от которого и наследуются. Не более. Наличие буфера этот подход не исключает, без него по сути и не обходится. Вот просто выписывание сжатых данных в поток могли бы сделать регулиремым (зачем-то же Flush метод придумали). У меня вообще такое впечатление, что класс на MS не доработали. Идея хорошая, но не доработали.
Здравствуйте, akasoft, Вы писали:
A>Хм. И какой оптимальный размер буфера? . Эксперименты не дали значительного улучшения коэффициента сжатия при увеличении объема буфера за 1 килобайт. Но размер входного окна у енкодера = 16646 байт, что бы это ни значило.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, SeLo, Вы писали:
SL>Это описывает лишь суть алгоритма сжатия (как и распаковки), который не предусматривает многократного прохода по данным. Данный сжимаются налету, и потому вписываются в идиалогию потоков (Stream), от которого и наследуются. Не более. Наличие буфера этот подход не исключает, без него по сути и не обходится. Вот просто выписывание сжатых данных в поток могли бы сделать регулиремым (зачем-то же Flush метод придумали). У меня вообще такое впечатление, что класс на MS не доработали. Идея хорошая, но не доработали.
Flush() это метод стрима. Идеология правильная. Сам создавай входной стрим, а уж как ты его будешь запонять это твои проблемы. Для сжатия данных нужен входящий поток и не более. Он сам будет брать данные нужными для него порциями.
и солнце б утром не вставало, когда бы не было меня
S>Flush() это метод стрима. Идеология правильная. Сам создавай входной стрим, а уж как ты его будешь запонять это твои проблемы. Для сжатия данных нужен входящий поток и не более. Он сам будет брать данные нужными для него порциями.
и...? или вы меня недопоняли, или я. какими порциями? где это регулируется? почему результыты компресси такие разные? понятно что идеалогия привильная, но вот класс этот GZip как-то криво реализованн