DeflateStream не работает на MemoryStream?
у меня есть следующий фрагмент кода:
MemoryStream resultStream = new MemoryStream();
string users = ""//Really long string goes here
BinaryFormatter bFormatter = new BinaryFormatter();
using (MemoryStream assignedUsersStream = new MemoryStream())
{
bFormatter.Serialize(assignedUsersStream, users);
assignedUsersStream.Position = 0;
using (var compressionStream =
new DeflateStream(resultStream, CompressionLevel.Optimal))
{
assignedUsersStream.CopyTo(compressionStream);
Console.WriteLine("Compressed from {0} to {1} bytes.",
assignedUsersStream.Length.ToString(),
resultStream.Length.ToString());
}
}
дело в том, что resultStream
всегда пусто!
что я делаю неправильно здесь?
3 ответов
поместите свою проверку WriteLine вне использования. Буфера еще не смыты.
using (DeflateStream compressionStream = new DeflateStream(resultStream, CompressionLevel.Optimal))
{
assignedUsersStream.CopyTo(compressionStream);
//Console.WriteLine("Compressed from {0} to {1} bytes.",
// assignedUsersStream.Length.ToString(), resultStream.Length.ToString());
}
Console.WriteLine("Compressed from {0} to {1} bytes.",
assignedUsersStream.Length, resultStream.ToArray().Length);
и в стороне, вам не нужны все эти ToString()
s в writeline.
PS: все, что делает BinaryFormatter со строкой, это запись байтов с префиксом длины. Если вам не нужен префикс (моя догадка), он может стать:
string users = "";//Really long string goes here
byte[] result;
using (MemoryStream resultStream = new MemoryStream())
{
using (DeflateStream compressionStream = new DeflateStream(resultStream,
CompressionLevel.Optimal))
{
byte[] inBuffer = Encoding.UTF8.GetBytes(users);
compressionStream.Write(inBuffer, 0, inBuffer.Length);
}
result = resultStream.ToArray();
}
обратное так же просто, но вам понадобится оценка максимальной длины для создания read-buffer:
string users2 = null;
using (MemoryStream resultStream = new MemoryStream(result))
{
using (DeflateStream compressionStream = new DeflateStream(resultStream,
CompressionMode.Decompress))
{
byte[] outBuffer = new byte[2048]; // need an estimate here
int length = compressionStream.Read(outBuffer, 0, outBuffer.Length);
users2 = Encoding.UTF8.GetString(outBuffer, 0, length);
}
}
вот ведь DeflateStream
не сбрасывает данные в базовый поток, пока он не будет закрыт. После того, как он закрыт,resultStream
будет содержать сжатые данные. Обратите внимание, что по умолчанию DeflateStream
закрывает базовый поток, когда он закрыт, но вы этого не хотите, поэтому вам нужно передать true
на
из исходного ответа (у меня недостаточно кредитов, чтобы проголосовать)
поместите свой контроль WriteLine вне using
это неполно и вводит в заблуждение. DeflateStream закрывается после того, как базовых resultStream DeflateStream выходит из области видимости. Поэтому resultStream.Длина бросков
Unhandled Exception: System.ObjectDisposedException: Cannot access a closed Stream.
Томас Левек прав => также установить leaveOpen
в true.
интересный вопрос с хорошими точки, поднятые HH и TL.