Brian Bush
asked on
UnBZip2 a Stream with SharpZipLib
I needed to compress a stream in memory using SharpZipLib and write out the base64encoded string:
https://www.experts-exchange.com/questions/21864314/BZip2-a-Stream-with-SharpZipLib.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
https://www.experts-exchange.com/questions/21864314/BZip2-a-Stream-with-SharpZipLib.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
Yeah, what you need is basically the same as the part of the code from the:
byte[] receivedCompressedBase64 = Convert.FromBase64String(s trInterimS torage);
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(receivedCompressed Base64 , 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(readStrea m, decompStream);
}
}
A
byte[] receivedCompressedBase64 = Convert.FromBase64String(s
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(receivedCompressed
}
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,
}
}
using (FileStream readStream = File.OpenRead(BZIP_PATH))
{
using (FileStream decompStream = File.Open(OUT_PATH, FileMode.Create))
{
BZip2.Decompress(readStrea
}
}
A
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.BZ ip2;
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)singl eByte);
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(com pressedByt es);
Console.WriteLine("Compres sed string (base64)");
Console.WriteLine(strInter imStorage) ;
/* END DISPLAY RESULTS */
byte[] receivedCompressedBase64 = Convert.FromBase64String(s trInterimS torage);
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(receivedCompr essedBase6 4))
{
// 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)sin gleByte);
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(decompressedBy tes, 0, (int)decomp.Length);
}
string strFinal = Encoding.ASCII.GetString(d ecompresse dBytes);
Console.WriteLine("Decompr essed string (base64)");
Console.WriteLine("[{0}]", strFinal);
Console.ReadLine();
}
private static void CheckFileExists()
{
if (!File.Exists(FILE_PATH))
throw new FileNotFoundException("Cou ld not find source file C:\test.txt");
}
}
}
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.BZ
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)singl
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(com
Console.WriteLine("Compres
Console.WriteLine(strInter
/* END DISPLAY RESULTS */
byte[] receivedCompressedBase64 = Convert.FromBase64String(s
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(receivedCompr
{
// 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)sin
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(decompressedBy
}
string strFinal = Encoding.ASCII.GetString(d
Console.WriteLine("Decompr
Console.WriteLine("[{0}]",
Console.ReadLine();
}
private static void CheckFileExists()
{
if (!File.Exists(FILE_PATH))
throw new FileNotFoundException("Cou
}
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Awesome. Thanks for your help.
--brian
--brian
Your welcome. Thanks for the points.
No problem. I quite like that byte by byte read actually - it means you can display progress as you go.
Something like this:
System.IO.StreamReader t = new System.IO.StreamReader("c:
string ss= t.ReadToEnd();
byte[] compressedBytes=Convert.Fr
System.IO.MemoryStream comp = new System.IO.MemoryStream(com
ICSharpCode.SharpZipLib.BZ
byte[] decompBytes = new byte[b.Length];
b.Read(decompBytes, 0, (int)b.Length);
System.IO.FileStream fs = new System.IO.FileStream("c:\t
fs.Write(decompBytes, 0, decompBytes.Length);
Hope this helps.