Nick
Nick

Reputation: 158

Read GZip compressed Data in Stream

My aim is to compress a file using gzip an then write the compressed bytes into an Xml section, which means that I need the compressed byte array in my code. All examples for GZip I found just wrote the bytes directly to a file.

So here is my code:

public ContainerFile(string[] inputFiles, string Output)
    {
        XmlDocument doc = new XmlDocument();
        XmlNode root;

        FileInfo fi;
        FileStream fstream;
        BinaryReader reader;
        GZipStream gstream;



        root = doc.CreateElement("compressedFile");
        doc.AppendChild(root);

        foreach (string f in inputFiles)
        {
            fstream = File.OpenRead(f);
            MemoryStream s = new MemoryStream();

            byte[] buffer = new byte[fstream.Length];
            // Read the file to ensure it is readable.
            int count = fstream.Read(buffer, 0, buffer.Length);
            if (count != buffer.Length)
            {
                fstream.Close();
                //Console.WriteLine("Test Failed: Unable to read data fromfile");
            return;
            }
            fstream.Close();

            gstream = new GZipStream(s, CompressionMode.Compress, true);
            gstream.Write(buffer, 0, buffer.Length);
            gstream.Flush();


            byte[] bytes = new byte[s.Length];

            s.Read(bytes, 0, bytes.Length);

            File.WriteAllBytes(@"c:\compressed.gz", bytes);

        }

for debugging reasons, I just tried to write the data into a file after it was loaded.

So, the length of the input file is ~4k bytes. As the degubber shows me, the length of the "bytes"- array is ~2k. So it looks like the size of the compressed byte array is right, but all values in it are 0.

Can s.o. help me?

Upvotes: 1

Views: 2694

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499760

Your Read call is trying to read from the end of the MemoryStream - you haven't "rewound" it. You could do that with s.Position = 0; - but it would be simpler to just call MemoryStream.ToArray.

Note that I would personally try not to read from streams assuming that the entire data will be available in one go, as you're doing to start with. You should also use using statements for streams to avoid leaking handles if an exception is thrown. However, using File.ReadAllBytes would be simpler anyway:

byte[] inputData = File.ReadAllBytes();
using (var output = new MemoryStream())
{
    using (var compression = new GZipStream(output, CompressionMode.Compress,
                                            true))
    {
        compression.Write(inputData, 0, inputData.Length);
    }
    File.WriteAllBytes(@"c:\compressed.gz", output.ToArray());
}

It's not clear why you're using a MemoryStream in the first place here, given that you're then writing the data out to a file...

Upvotes: 4

Related Questions