Итак, я пытаюсь сжать массив байтов (через Stream). ExtendedStream - это просто класс, который я сделал с интерфейсом с базовым потоком (по умолчанию MemoryStream). Если я беру свои исходные данные, сжимаю их, распаковываю, а затем сравниваю размер распакованных данных с размером исходных данных (до сжатия), оказывается, что он меньше оригинала.Исходный файл больше, чем файл GZip для распаковки
Оригинал Длина: 51695, Сжатый длина: 26014, расжатая длина: 48685.
Я хранящие плитки (7 байт). Сжатие с использованием классов GZip, предоставляемых в пространстве имен System.IO.Compression.
public static ExtendedStream GZipDecompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream();
GZipStream decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, true);
int b = -1;
while ((b = decompressStream.ReadByte()) != -1)
{
outStream.WriteByte((Byte)b);
}
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
public static ExtendedStream GZipCompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream(); // base stream is a memorystream
GZipStream compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, true);
compressStream.Write(stream.ToArray(), 0, (int)stream.Length);
compressStream.Flush();
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
Надеюсь, этого достаточно информации.
Во-первых, вы должны звонить. Поместите объекты GZipStream, когда вы закончите. Также при записи вам нужно позвонить .Flush на outStream после того, как вы избавитесь от своего GZipStream. В-третьих, если это .NET4, используйте метод .CopyTo для основного элемента вашего входного потока, чтобы скопировать данные из ввода в выходной файл (вместо использования .ToArray, который не будет масштабироваться по мере увеличения ваших потоков). – Joe
Нет, вам не нужно вызывать flush на «outStream» при распаковке или сжатии. Данные уже находятся в потоке. Flushing ничего не сделал бы, так как это MemoryStream (и FYI MemoryStream переопределяет Flush, чтобы он ничего не делал). Я сохраню метод CopyTo, но GC просто исправит все для меня (небрежный дизайн, который я знаю, но это не цель дизайна № 1). –
@ Супа, нет; Джо прав. Вы ** должны должны ** формально закрыть/удалить потоки сжатия. Флеш не может быть пустым, если он не знает, что больше ничего не происходит, что происходит только при закрытии. Ограничение сжатия. Это абсолютно критично в сжатии (как вы думаете, я еще подчеркивал это достаточно?). Btw: копирование отдельных байтов - это ужасный способ сделать это. –