can my decompress method be written in a better way

T

Tony Johansson

Hello!

In this program I compress the string "Test" by using DeflateStream in
method Compress.
I decompress in three different ways by using three different methods.
All three methods works and give back the original string.

My question is concering the last method Decompress3 if it's possible to
reduce the code here because I use the returned
value from DeflateStream.Read to know how many bytes the actual string is
and then I use a for loop to extract these ?
I assume that Decompress3 can't be done in a better way.

public static byte[] Compress(string value)
{
byte[] document = new UTF8Encoding().GetBytes(value);
MemoryStream strm = new MemoryStream();
DeflateStream deflate = new DeflateStream(strm,
CompressionMode.Compress);
deflate.Write(document, 0, document.Length);
deflate.Close();
byte[] result = strm.ToArray();
//string s = System.Text.ASCIIEncoding.UTF8.GetString(result);
return result;
}

public static string Decompress1(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
StreamReader reader = new StreamReader(ds);
string result = reader.ReadToEnd();
ds.Close();
ms.Close();
return result;
}

public static string Decompress2(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
int myByte = ds.ReadByte();
string result = string.Empty;
while (myByte != -1)
{
result += (char)myByte;
myByte = ds.ReadByte();
}
ds.Close();
ms.Close();
return result;
}

public static string Decompress3(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
byte[] data = new byte[ms.Length];
int rByte = ds.Read(data, 0, data.Length);
StringBuilder sb = new StringBuilder(rByte);
for (int i = 0; i < rByte; i++)
sb.Append((char)data);
string result = sb.ToString();
ds.Close();
ms.Close();
return result;
}

static void Main(string[] args)
{
string input = "test";
byte[] compressedData = Compress(input);
if (input == Decompress1(compressedData))
Console.WriteLine("Equal");

if (input == Decompress2(compressedData))
Console.WriteLine("Equal");

if (input == Decompress3(compressedData))
Console.WriteLine("Equal");
}

//Tony
 
A

Arne Vajhøj

In this program I compress the string "Test" by using DeflateStream in
method Compress.
I decompress in three different ways by using three different methods.
All three methods works and give back the original string.

My question is concering the last method Decompress3 if it's possible to
reduce the code here because I use the returned
value from DeflateStream.Read to know how many bytes the actual string is
and then I use a for loop to extract these ?
I assume that Decompress3 can't be done in a better way.

public static byte[] Compress(string value)
{
byte[] document = new UTF8Encoding().GetBytes(value);
MemoryStream strm = new MemoryStream();
DeflateStream deflate = new DeflateStream(strm,
CompressionMode.Compress);
deflate.Write(document, 0, document.Length);
deflate.Close();
byte[] result = strm.ToArray();
//string s = System.Text.ASCIIEncoding.UTF8.GetString(result);
return result;
}

public static string Decompress1(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
StreamReader reader = new StreamReader(ds);
string result = reader.ReadToEnd();
ds.Close();
ms.Close();
return result;
}

public static string Decompress2(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
int myByte = ds.ReadByte();
string result = string.Empty;
while (myByte != -1)
{
result += (char)myByte;
myByte = ds.ReadByte();
}
ds.Close();
ms.Close();
return result;
}

public static string Decompress3(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
byte[] data = new byte[ms.Length];
int rByte = ds.Read(data, 0, data.Length);
StringBuilder sb = new StringBuilder(rByte);
for (int i = 0; i< rByte; i++)
sb.Append((char)data);
string result = sb.ToString();
ds.Close();
ms.Close();
return result;
}

static void Main(string[] args)
{
string input = "test";
byte[] compressedData = Compress(input);
if (input == Decompress1(compressedData))
Console.WriteLine("Equal");

if (input == Decompress2(compressedData))
Console.WriteLine("Equal");

if (input == Decompress3(compressedData))
Console.WriteLine("Equal");
}


Only solution #1 is correct.

Solution #2:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)

(and besides it is relative inefficient to use single byte Read)

Solution #3:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)
- ms.Length contains the compress length which very well may be
shorter than the uncompressed length so you risk truncating
data

(furthermore I am not sure whether Read is guaranteed to
fill the entire buffer, so a while loop may be necessary)

Arne
 
A

Arne Vajhøj

In this program I compress the string "Test" by using DeflateStream in
method Compress.
I decompress in three different ways by using three different methods.
All three methods works and give back the original string.

My question is concering the last method Decompress3 if it's possible to
reduce the code here because I use the returned
value from DeflateStream.Read to know how many bytes the actual string is
and then I use a for loop to extract these ?
I assume that Decompress3 can't be done in a better way.

public static byte[] Compress(string value)
{
byte[] document = new UTF8Encoding().GetBytes(value);
MemoryStream strm = new MemoryStream();
DeflateStream deflate = new DeflateStream(strm,
CompressionMode.Compress);
deflate.Write(document, 0, document.Length);
deflate.Close();
byte[] result = strm.ToArray();
//string s = System.Text.ASCIIEncoding.UTF8.GetString(result);
return result;
}

public static string Decompress1(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
StreamReader reader = new StreamReader(ds);
string result = reader.ReadToEnd();
ds.Close();
ms.Close();
return result;
}

public static string Decompress2(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
int myByte = ds.ReadByte();
string result = string.Empty;
while (myByte != -1)
{
result += (char)myByte;
myByte = ds.ReadByte();
}
ds.Close();
ms.Close();
return result;
}

public static string Decompress3(byte[] value)
{
MemoryStream ms = new MemoryStream(value);
DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
byte[] data = new byte[ms.Length];
int rByte = ds.Read(data, 0, data.Length);
StringBuilder sb = new StringBuilder(rByte);
for (int i = 0; i< rByte; i++)
sb.Append((char)data);
string result = sb.ToString();
ds.Close();
ms.Close();
return result;
}

static void Main(string[] args)
{
string input = "test";
byte[] compressedData = Compress(input);
if (input == Decompress1(compressedData))
Console.WriteLine("Equal");

if (input == Decompress2(compressedData))
Console.WriteLine("Equal");

if (input == Decompress3(compressedData))
Console.WriteLine("Equal");
}


Only solution #1 is correct.

Solution #2:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)

(and besides it is relative inefficient to use single byte Read)

Solution #3:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)
- ms.Length contains the compress length which very well may be
shorter than the uncompressed length so you risk truncating
data

(furthermore I am not sure whether Read is guaranteed to
fill the entire buffer, so a while loop may be necessary)


And for #1 I would probably pick a constructor for StreamReader
where you can explicit specify the Encoding to UTF-8 - not
everyone can remember what the default encoding is for
StreamReader.

Arne
 
A

Arne Vajhøj

Arne said:
[...]
Solution #2:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)

(and besides it is relative inefficient to use single byte Read)

Solution #3:
- assumes a single byte encoding (and you used UTF8 for
compress which is not a single byte encoding)
- ms.Length contains the compress length which very well may be
shorter than the uncompressed length so you risk truncating
data

To be more specific: solutions #2 and #3 not only assume "a single byte
encoding", they assume a non-existent single-byte encoding, one that
encodes all characters from 0 to 255 as single bytes that match the
character values for UTF-16 from 0 to 255.

ISO-8859-1 ??

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top