Click here to Skip to main content
15,881,812 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey guys

I need to compress a byte[] with the System.IO.Compression.DeflateStream

Here's the code I have so far:
C#
byte[] uncompressedCsvFile = File.ReadAllBytes(csvFileName);
byte[] compressedCsvFile;

using (MemoryStream outStream = new MemoryStream())
{
    using (DeflateStream compress = new DeflateStream(outStream, CompressionMode.Compress, true))
    {
        compress.Write(uncompressedCsvFile, 0, uncompressedCsvFile.Length);
        compress.Flush();
        compress.Close();
    }

    compressedCsvFile = new byte[outStream.Length];
    outStream.Read(compressedCsvFile, 0, (int)outStream.Length);
}


outStream.Lentgh is much smaller than the uncompressed byte[], but after i try to read the MemoryStream my compressed byte[] just contains 0's.

In the debuger I noticed that in outStream's non public members _buffer is the expected size and contains bytes other than 0.

Am I doing something wrong reading the memory stream?

NOTE: I need to compress this array to send it over the wire and decompress it on the other side to work with. Compressing it to a file won't solve my problem.
Posted

The problem was getting the data out of the memory stream. outStream.ToArray(); returnes the compressed bytes.

Working Compression Method:

C#
public static byte[] CompressData(string fileName)
{
    byte[] uncompressedFileData = new byte[0];
    byte[] compressedFileData = new byte[0];

    try
    {
        var stopwatch = new Stopwatch();
        stopwatch.Reset();
        stopwatch.Start();

        if (!File.Exists(fileName))
        {
            throw new FileNotFoundException(fileName + " not found");
        }

        uncompressedFileData = File.ReadAllBytes(fileName);

        using (var outStream = new MemoryStream())
        {
            using (var compress = new DeflateStream(outStream, CompressionMode.Compress, true))
            {
                compress.Write(uncompressedFileData, 0, uncompressedFileData.Length);
                compress.Flush();
                compress.Close();
            }
            compressedFileData = outStream.ToArray();
        }

        stopwatch.Stop();
#if DEBUG
        Console.WriteLine("Compressed {0} bytes to {1} bytes in {2} seconds", uncompressedFileData.Length, compressedFileData.Length, stopwatch.Elapsed.TotalSeconds);
#endif
    }
    catch (Exception ex)
    {
        m_Log.Error(ex.Message, ex);
    }

    return compressedFileData;
}
 
Share this answer
 
Comments
OriginalGriff 11-May-10 4:14am    
Yep that works as well - because the ToArray effectively does the seek for you. It is worth remembering that you must reposition streams before reading if you are writing to them, or you will read data from immediately after the last write.
Harvey Saayman 11-May-10 6:22am    
That makes sense yes :-) thanks Griff!
Your stream is at the end when you read it. Try this:
compressedCsvFile = new byte[outStream.Length];
if (outStream.CanSeek)
    {
    outStream.Seek(0, SeekOrigin.Begin);
    }
outStream.Read(compressedCsvFile, 0, (int)outStream.Length);
You shouldn't need the CanSeek test since a memory stream can always seek, but it is worth including.
 
Share this answer
 
Comments
Harvey Saayman 11-May-10 3:59am    
It seems that I had a different problem: I answered my own question with a working code example.
Thanks though :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900