?
Solved

UnBZip2 a Stream with SharpZipLib

Posted on 2006-05-25
7
Medium Priority
?
1,203 Views
Last Modified: 2007-12-19
I needed to compress a stream in memory using SharpZipLib and write out the base64encoded string:
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21864314.html

Now I need to do the reverse.

I want to:
1. open a text file that contains a base64encoded string
2. decode it
3. UnBZip2 it
4. write out the file.

Simple enough?

--brian
0
Comment
Question by:Brian Bush
  • 4
  • 2
7 Comments
 
LVL 9

Expert Comment

by:noulouk
ID: 16767874
Hi brian,

Something like this:

System.IO.StreamReader t = new System.IO.StreamReader("c:\test.bzip2");
            string ss= t.ReadToEnd();
            byte[] compressedBytes=Convert.FromBase64String(ss);
            System.IO.MemoryStream comp = new System.IO.MemoryStream(compressedBytes);

            ICSharpCode.SharpZipLib.BZip2.BZip2InputStream b = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(comp);
            byte[] decompBytes = new byte[b.Length];
            b.Read(decompBytes, 0, (int)b.Length);

            System.IO.FileStream fs = new System.IO.FileStream("c:\test.txt", System.IO.FileMode.Create);
            fs.Write(decompBytes, 0, decompBytes.Length);

Hope this helps.
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16769445
Yeah, what you need is basically the same as the part of the code from the:

byte[] receivedCompressedBase64 = Convert.FromBase64String(strInterimStorage);

onwards, but using
               //      open the file into a stream
               using (FileStream fs = File.OpenRead(FILE_PATH))
               {
                    //     and read into a byte array
                    receivedCompressedBase64 = new byte[fs.Length];
                    fs.Read(receivedCompressedBase64 , 0, (int)fs.Length);
               }

to read in the bytes and then writing out a file. Again, I would use a "using" with the output FileStream, or at least ensure that you flush and close the FileStream.

The main problem is again going to be the truncation.

An alternative, if you are just worried about storing in a file and not about the Base64 format, would be:
      using (FileStream readStream = File.OpenRead(FILE_PATH))
      {
            using (FileStream compStream = File.Open(BZIP_PATH, FileMode.Create))
            {
                  BZip2.Compress(readStream, compStream, 4096);
            }
      }
                  
      using (FileStream readStream = File.OpenRead(BZIP_PATH))
      {
            using (FileStream decompStream = File.Open(OUT_PATH, FileMode.Create))
            {
                  BZip2.Decompress(readStream, decompStream);
            }
      }

A
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16769744
This gets round all the problems I mentioned. Write to file version to follow.

There is a key line in here that will make it work/break, and that is the decomp.Seek(0, SeekOrigin.Begin); line. Try taking that out and see what happens. Basically, as the stream position is at the end of the decompressed bytes that have been written, the byte[] decompressedBytes will not be filled with anything.

using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.BZip2;

namespace ConsoleApplication1
{

      class Program
      {
            const string FILE_PATH = @"C:\test.txt";
            const string BZIP_PATH = @"C:\test2.bzip2";
            const string OUT_PATH = @"C:\test.out.txt";
            static void Main(string[] args)
            {
                  CheckFileExists();

                  byte[] compressedBytes = null;

                  //       open the file into a stream
                  using (FileStream fs = File.OpenRead(FILE_PATH))
                  {
                        //      compress onto a memory stream
                        using (MemoryStream mem = new MemoryStream())
                        {
                              //      now create the compression stream based on the memory stream
                              using (BZip2OutputStream comp = new BZip2OutputStream(mem, 4096))
                              {
                                    int singleByte = fs.ReadByte();
                                    while (singleByte != -1)
                                    {
                                          comp.WriteByte((byte)singleByte);
                                          singleByte = fs.ReadByte();
                                    }
                              }      // the using statement ensures a flush, finalize and close

                              //      now we write the memorystream to the interim byte array to show there are now hidden tricks
                              compressedBytes = mem.ToArray();
                        }
                  }

                  /* DISPLAY RESULTS */
                  //      COnvert the bytes to a string
                  string strInterimStorage = Convert.ToBase64String(compressedBytes);

                  Console.WriteLine("Compressed string (base64)");
                  Console.WriteLine(strInterimStorage);
                  /* END DISPLAY RESULTS */

                  byte[] receivedCompressedBase64 = Convert.FromBase64String(strInterimStorage);
                  byte[] decompressedBytes;
                  //      decompress to a memory stream using a memory stream to access the byte array
                  using (MemoryStream decomp = new MemoryStream())
                  {
                        using (MemoryStream comp = new MemoryStream(receivedCompressedBase64))
                        {
                              //      now create the decompression stream based on the input memory stream
                              using (BZip2InputStream bzdecomp = new BZip2InputStream(comp))
                              {
                                    int singleByte = bzdecomp.ReadByte();
                                    while (singleByte != -1)
                                    {
                                          decomp.WriteByte((byte)singleByte);
                                          singleByte = bzdecomp.ReadByte();
                                    }
                              }      // the using statement ensures a flush, finalize and close
                        }
                        decomp.Flush();
                        decomp.Seek(0, SeekOrigin.Begin);
                        decompressedBytes = new byte[decomp.Length];
                  
                        decomp.Read(decompressedBytes, 0, (int)decomp.Length);
                  }

                  string strFinal = Encoding.ASCII.GetString(decompressedBytes);
                  Console.WriteLine("Decompressed string (base64)");
                  Console.WriteLine("[{0}]", strFinal);
                  Console.ReadLine();
            }
            private static void CheckFileExists()
            {
                  if (!File.Exists(FILE_PATH))
                        throw new FileNotFoundException("Could not find source file C:\test.txt");
            }
      }
}
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Accepted Solution

by:
AGBrown earned 2000 total points
ID: 16769801
Here's the read from file/write to file/read from file/write to file version

using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.BZip2;

namespace ConsoleApplication1
{

      class Program
      {
            const string FILE_PATH = @"C:\test.txt";
            const string BZIP_PATH = @"C:\test2.bzip2";
            const string OUT_PATH = @"C:\test2.out.txt";
            static void Main(string[] args)
            {
                  CheckFileExists();

                  byte[] compressedBytes = null;


                  //       open the file into a stream
                  using (FileStream fs = File.OpenRead(FILE_PATH))
                  {
                        //      compress onto a memory stream
                        using (MemoryStream mem = new MemoryStream())
                        {
                              //      now create the compression stream based on the memory stream
                              using (BZip2OutputStream comp = new BZip2OutputStream(mem, 4096))
                              {
                                    int singleByte = fs.ReadByte();
                                    while (singleByte != -1)
                                    {
                                          comp.WriteByte((byte)singleByte);
                                          singleByte = fs.ReadByte();
                                    }
                              }      // the using statement ensures a flush, finalize and close

                              //      now we write the memorystream to the interim byte array to show there are now hidden tricks
                              compressedBytes = mem.ToArray();
                        }
                  }

                  //      Write to file
                  using (StreamWriter sw = new StreamWriter(BZIP_PATH, false, Encoding.UTF8))
                  {
                        sw.Write(Convert.ToBase64String(compressedBytes));
                  }

                  //      END COMPRESSION, BEGIN DECOMPRESSION

                  byte[] receivedCompressedBase64;

                  //      Read from file
                  using (StreamReader sr = File.OpenText(BZIP_PATH))
                  {
                        string strCompressed64 = sr.ReadToEnd();
                        receivedCompressedBase64 = Convert.FromBase64String(strCompressed64);
                  }

                  //      decompress to a memory stream using a memory stream to access the byte array
                  using (FileStream decomp = File.Open(OUT_PATH, FileMode.Create)) // target memory stream to get the decompressed data
                  {
                        using (MemoryStream comp = new MemoryStream(receivedCompressedBase64)) // memory stream to read from the byte array
                        {
                              //      now create the decompression stream based on the input memory stream
                              using (BZip2InputStream bzdecomp = new BZip2InputStream(comp))
                              {
                                    //      write from the decompression stream to the target stream one byte at a time
                                    int singleByte = bzdecomp.ReadByte();
                                    while (singleByte != -1)
                                    {
                                          decomp.WriteByte((byte)singleByte);
                                          singleByte = bzdecomp.ReadByte();
                                    }
                              }      // the using statement ensures a flush, finalize and close
                        }
                  }
            }
            private static void CheckFileExists()
            {
                  if (!File.Exists(FILE_PATH))
                        throw new FileNotFoundException("Could not find source file C:\test.txt");
            }
      }
}
0
 
LVL 6

Author Comment

by:Brian Bush
ID: 16769811
Awesome. Thanks for your help.
--brian
0
 
LVL 9

Expert Comment

by:noulouk
ID: 16769860
Your welcome. Thanks for the points.
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16769877
No problem. I quite like that byte by byte read actually - it means you can display progress as you go.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Loops Section Overview
Suggested Courses
Course of the Month17 days, 10 hours left to enroll

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question