WCF Compress And Decompress Mehtod Problem Gzip Image Data(Binary) C# - c#

i have two method for compress and decompress base64 image data in sql
server
my decompress method for read data in sql its work but compressing
return wrong data please help me ...
public static Byte[] BinaryCompress(Byte[] InputStream)
{
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream x = new GZipStream(ms, CompressionMode.Compress, true))
{
byte[] inputBytes = (byte[])InputStream;
x.Write(inputBytes, 0, inputBytes.Length);
}
return ms.ToArray();
}
}

public static Byte[] BinaryDecompress(Byte[] InputBinary)
{
byte[] inputBytes = (byte[])InputBinary;
using (MemoryStream msin = new MemoryStream(inputBytes))
{
using (GZipStream x = new GZipStream(msin, CompressionMode.Decompress))
{
using (MemoryStream msout = new MemoryStream())
{
int num = x.ReadByte();
while (num != -1)
{
msout.WriteByte((byte)num);
num = x.ReadByte();
}
return msout.ToArray(); ;
}
}
}
}

Could you please provide more specific exception by using below code?
public static Byte[] BinaryCompress(Byte[] InputStream)
{
try
{
MemoryStream ms = new MemoryStream();
try
{
GZipStream x = new GZipStream(ms, CompressionMode.Compress, true)
byte[] inputBytes = (byte[])InputStream;
x.Write(inputBytes, 0, inputBytes.Length);
}
catch (Exception ex)
{
Console.Write(ex.StackTrace);
}
return ms.ToArray();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
throw;
}
}

Related

How to compress a Byte array without stream or system io

I'm trying to encode an image into a byte array and send it to a server.
the encoding and sending parts wok fine but my problem is that the byte array is too large and takes too long to send so I thought compressing it would make it go faster. but the actual problem is that I CAN NOT use system.io or streams. and I'm targeting .net 2.0.
Thank you.
using System.IO;
using System.IO.Compression;
code:
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
{
dstream.Write(data, 0, data.Length);
}
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
}
Updated
Use 7zip library:
http://www.splinter.com.au/compressing-using-the-7zip-lzma-algorithm-in/
// Convert the text into bytes
byte[] DataBytes = ASCIIEncoding.ASCII.GetBytes(OriginalText);
// Compress it
byte[] Compressed = SevenZip.Compression.LZMA.SevenZipHelper.Compress(DataBytes);
// Decompress it
byte[] Decompressed = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(Compressed);
Compress
public static byte[] Compress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
{
dstream.Write(inputData, 0, inputData.Length);
}
return output.ToArray();
}
OR
public static byte[] Compress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
using (var compressIntoMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressIntoMs,
CompressionMode.Compress), BUFFER_SIZE))
{
gzs.Write(inputData, 0, inputData.Length);
}
return compressIntoMs.ToArray();
}
}
Decompress
public static byte[] Decompress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
}
OR
public static byte[] Decompress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
using (var compressedMs = new MemoryStream(inputData))
{
using (var decompressedMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressedMs, CompressionMode.Decompress), BUFFER_SIZE))
{
gzs.CopyTo(decompressedMs);
}
return decompressedMs.ToArray();
}
}
}

System.OutOfMemory exception is thrown while Decompress bytes

I am compressing the bytes and again while decompressing it I get OOM exception. I am not able to understand why am I getting this error when I have enough memory to store it.
The data is around 20MB after being compressed that is to be decompressed. But I always get OutOfMemory exception.
Below is the code for the same.
public byte[] Compress(byte[] data)
{
byte[] compressArray = null;
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
compressArray = memoryStream.GetBuffer();
memoryStream.Dispose();
}
}
catch (Exception exception)
{
LogManager.LogEvent(EventLogEntryType.Error, exception.Message);
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
compressStream.Dispose();
}
decompressedArray = decompressedStream.GetBuffer();
decompressedStream.Dispose();
}
}
catch (Exception exception)
{
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
Below is the stack trace for better understanding.
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Stream.CopyTo(Stream destination)
at Symtrax.SQConsole.ConsoleConnectClass.Decompress_Bytes(Byte[] data) in c:\Developement\BI\branch_5.0\MapDesignerUNICODE\ConsoleConnector\SQConsole\ConsoleConnectClass.cs:line 3710
I found many relavant questions regarding this but none of them seem to solve my issue.
Since I have less reputation points I am unable to comment. Hence had to post question. Thanks in advance.
As already stated in the comments you're getting the internal buffer with GetBuffer that has different length characteristics then just calling ToArray.
I have added some dump statements in your code so LINQPad can reveal what is happening:
public byte[] Compress(byte[] data)
{
byte[] compressArray = null;
data.Length.Dump("initial array length");
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
memoryStream.GetBuffer().Length.Dump("buffer compress len");
compressArray = memoryStream.ToArray();
compressArray.Length.Dump("compress array len");
// no need to call Dispose, using does that for you
//memoryStream.Dispose();
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
// no need, using does that
//compressStream.Dispose();
}
decompressedStream.GetBuffer().Length.Dump("buffer decompress len");
decompressedArray = decompressedStream.ToArray();
decompressedArray.Length.Dump("decompress array len");
// no need, using does that
decompressedStream.Dispose();
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
This is the output:
initial array length
248404
buffer compress len
262144
compress array len
189849
buffer decompress len
327680
decompress array len
248404
As you can see from these numbers you'll have very a different length count. You could possible get away with those extra bytes if the Deflate protocol would allow for byte streams that have extra bytes.
The use of GetBuffer instead of ToArray might seem beneficial but I expect the memory allocation and CPU ticks needed for copying of the final array be neglect able, specially if the memory stream is disposed anyway. That fact actually reduces the memory footprint a bit.
If you still insist on re-using the memory stream buffer make sure to also return and provide the actual length in the buffer:
public byte[] Compress(byte[] data, out int len)
{
byte[] compressArray = null;
data.Length.Dump("initial array length");
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
// keep the stream open, we need the length!
using (DeflateStream deflateStream = new DeflateStream(
memoryStream,
CompressionMode.Compress,
true))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
// output length
len = (int) memoryStream.Length;
compressArray = memoryStream.GetBuffer();
}
}
catch (Exception exception)
{
exception.Dump();
len =-1;
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data, ref int len)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
// use the overload that let us limit the memorystream buffer
using (MemoryStream compressStream = new MemoryStream(data,0, len))
{
// keep the stream open
using (DeflateStream deflateStream = new DeflateStream(
compressStream,
CompressionMode.Decompress,
true))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
}
// output length
decompressedArray = decompressedStream.GetBuffer();
len = (int) decompressedStream.Length;
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
If you use above code you'll have call it like this:
int len;
var cmp = Compress(Encoding.UTF8.GetBytes(sb.ToString()), out len);
var dec = Decompress_Bytes(cmp,ref len);
Notice to use the bytes in dec you need to only take the first len number of bytes into account. Practically this is done by using Array.Copy which defeats this solution and brings us back to the one which does call ToArray...

How to Encrypt and Decrypt an image in WP8?

I want to Encrypt an image and save in Isolated storage and image decryption while reading.I am able to do normal text data but I didn't find solution for an image.And further I need to encrypt and decrypt PDF/Doc files.
Below is my code
MemoryStream stream = new MemoryStream();
compressedStream.Seek(0, SeekOrigin.Begin);
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isStore.FileExists(selectedImageName))
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(selectedImageName, FileMode.Create, FileAccess.Write))
{
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = compressedStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
To encrypt normal text using below code
public static byte[] Encrypt(string text, string strCacheKey)
{
try
{
return ProtectedData.Protect((Encoding.UTF8.GetBytes(text)), GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Thanks in advance.
Finally got answer to encrypt/decrypt Images
Encryption Code:
public static byte[] EncryptImage(byte[] encryptedimage, string strCacheKey)
{
try
{
return ProtectedData.Protect(encryptedimage, GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Decryption Code:
public static byte[] DecryptImage(byte[] decryptedimage, string strCacheKey)
{
try
{
return ProtectedData.Unprotect(decryptedimage, GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Code for storing in Isolated Storage:
byte[] ibytes = new byte[attachmentStream.Length];
byte[] ImageByte = TextImageEncryptionDecryption.EncryptImage(ibytes, App.cacheKey);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream targetStream = new IsolatedStorageFileStream(selectedImageName,
FileMode.Create, FileAccess.Write, store))
{
targetStream.Write(ImageByte, 0, ImageByte.Length);
}
Code to Read image from ISO:
using (var stream = iso.OpenFile(name, FileMode.Open, FileAccess.Read))
{
byte[] ImgStr = ReadFully(stream);
byte[] Img = TextImageEncryptionDecryption.DecryptImage(ImgStr, App.cacheKey);
Stream Imagestream = new MemoryStream(Img);
image.SetSource(Imagestream);
imgAttach = image;
}
return imgAttach;
}
Cheers !!

decompress by gzip failed

i'm write one pair function too compress and decompress but decompress failed
this is my code
public static byte[] CompressByGzip( byte[] input ) {
using(var ims = new MemoryStream()) {
using(var gzip = new GZipStream(ims, CompressionMode.Compress)) {
gzip.Write(input, 0, input.Length);
return ims.ToArray();
}
}
}
public static byte[] DecompressByGzip( byte[] input ) {
using(var ims = new MemoryStream()) {
using(var gzip = new GZipStream(ims, CompressionMode.Decompress)) {
using(var outms = new MemoryStream()) {
ims.Write(input, 0, input.Length);
byte[] buf = new byte[bufLength];
int len=0;
while((len=gzip.Read(buf, 0, buf.Length))>0) {
outms.Write(buf, 0, len);
}
return outms.ToArray();
}
}
}
}
when i debug,i found the gzip can't read,it has inner Exception....
Length = “gzip.Length”引发了“System.NotSupportedException”类型的异常
Your compressed output CompressByGzip is wrong. You need to flush the gzip stream before converting to array. Move the return ... statement.
public static byte[] CompressByGzip( byte[] input )
{
using(var ims = new MemoryStream())
{
using(var gzip = new GZipStream(ims, CompressionMode.Compress))
{
gzip.Write(input, 0, input.Length);
}
return ims.ToArray();
}
}
Here is what you can do for .Net 4.5
Compress
public static byte[] Compress(byte[] data, CompressionLevel level = CompressionLevel.Fastest)
{
using (var memory = new MemoryStream())
{
using (var gzip = new GZipStream(memory, level, true))
{
gzip.Write(data, 0, data.Length);
}
return memory.ToArray();
}
}
Decompress
public static byte[] Decompress(byte[] byteData)
{
if (byteData == null)
throw new ArgumentNullException("byteData", #"inputData must be non-null");
using (var compressedMs = new MemoryStream(byteData))
{
using (var decompressedMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressedMs, CompressionMode.Decompress), 4096))
{
gzs.CopyTo(decompressedMs);
}
return decompressedMs.ToArray();
}
}
}

Compress and decompress a Stream with Compression.DeflateStream

I am trying to compress and decompress a Stream using Compression.DeflateStream. Compressing seems to work correctly since the code below compresses my Stream to a 110 bytes long array. However, reading the decompressed Stream results in an empty string.
class Program
{
static void Main(string[] args)
{
// Compress a random string value
string value = Path.GetRandomFileName();
byte[] compressedBytes;
using (var writer = new StreamWriter(new MemoryStream()))
{
writer.Write(value);
writer.Flush();
writer.BaseStream.Position = 0;
compressedBytes = Compress(writer.BaseStream);
}
// Decompress compressed bytes
Stream decompressedStream = Decompress(compressedBytes);
// here already applies: decompressedStream.Length == 0
using (var reader = new StreamReader(decompressedStream))
{
string decompressedValue = reader.ReadToEnd();
if (value == decompressedValue)
Console.WriteLine("Success");
else
Console.WriteLine("Failed");
}
}
private static byte[] Compress(Stream input)
{
using (var compressStream = new MemoryStream())
using (var compressor = new DeflateStream(compressStream, CompressionMode.Compress))
{
input.CopyTo(compressor);
return compressStream.ToArray();
}
}
private static Stream Decompress(byte[] input)
{
var output = new MemoryStream();
using (var compressStream = new MemoryStream(input))
using (var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress))
decompressor.CopyTo(output);
output.Position = 0;
return output;
}
}
Can anyone help me on this one?
Many thanks.
Fix your Compress function:
private static byte[] Compress(Stream input)
{
using(var compressStream = new MemoryStream())
using(var compressor = new DeflateStream(compressStream, CompressionMode.Compress))
{
input.CopyTo(compressor);
compressor.Close();
return compressStream.ToArray();
}
}
compressed stream was not flushed before returning the resulting byte array.
All those answers are far away from ideal form because all of you forgot that "using" disposing and closing streams its means that additional Close() is not needed. I think that ideal code will be like this:
public static class CompressionHelper
{
public static byte[] Compress(byte[] data)
{
byte[] compressArray = null;
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
}
compressArray = memoryStream.ToArray();
}
}
catch (Exception exception)
{
// do something !
}
return compressArray;
}
public static byte[] Decompress(byte[] data)
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);
}
}
decompressedArray = decompressedStream.ToArray();
}
}
catch (Exception exception)
{
// do something !
}
return decompressedArray;
}
}
Try closing the streams:
class Program
{
static void Main(string[] args)
{
// Compress a random string value
string value = DateTime.Now.ToLongTimeString();
byte[] compressedBytes;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value)))
{
compressedBytes = Compress(stream);
}
// Decompress compressed bytes
using (var decompressedStream = Decompress(compressedBytes))
using (var reader = new StreamReader(decompressedStream))
{
string decompressedValue = reader.ReadToEnd();
if (value == decompressedValue)
Console.WriteLine("Success");
else
Console.WriteLine("Failed");
}
}
public static byte[] Compress(Stream input)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
input.CopyTo(zipStream);
zipStream.Close();
return compressedStream.ToArray();
}
}
public static Stream Decompress(byte[] data)
{
var output = new MemoryStream();
using(var compressedStream = new MemoryStream(data))
using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
{
zipStream.CopyTo(output);
zipStream.Close();
output.Position = 0;
return output;
}
}
}

Categories