Skip to main content
Home Forums Silverlight Programming Programming with .NET - General how to compress file!
22 replies. Latest Post by SaurabhAgg on July 1, 2009.
(0)
joji777
Member
80 points
213 Posts
06-11-2009 5:02 PM |
Hi,
On button click event I am showing a Open file dialogue, and user can select audio file. that is working fine.
Now I want to compress user selected file (.zip) version and upload it or save it in isolated storage.
selcting a file, uploading it, saving it in isolated storage, all working fine. only i am unable to compress the file, can anyone help me for that ?
is it possible to create GZip compressed file ??
Regards
ksleung
Contributor
5198 points
993 Posts
06-11-2009 5:21 PM |
You have several choices:
(1) roll your own compress/decompress, for example, Huffman encoding. This may be a good option if you know exactly what you are doing and your data has a specific structure.
(2) use SharpZipLib, GPL licensed.
(3) use ZipForge from ComponentAce. Open source and not GPL licensed.
For some reason every time this question is asked, someone will say it is supported natively by SL. I love to be wrong about this, but it is supported only in .NET, not SL.
BTW, if the only thing you are interested is decompress (say you download a zip file from the server), you don't need any of these as decompress is natively supported by SL (for obvious reason)!
06-12-2009 3:53 AM |
Probably sharplibzip is quick and better solution. So I downloaded the project compile it and got icsharpcode.sharpziplib.dll
now ia m trying to add it in my silverlight project in reference and i see error
"You can't add reference as it was not built against silverlight runtime. SL project only work with SL assemblies"
Can anyone help me how to use sharpziplib in silverlight project?
06-12-2009 4:06 AM |
SharpZipLib is probably a WPF application in its packaged form. You need to create a SL library, add files, and compile.
06-12-2009 7:35 AM |
i have done that, and it works fine, but i am not done with the task.
how can i store a zipped file in isolated storage? user select an audio and i want to zip that file and store it in isolated storge.
how can i find the path of isolatedstoreage??
regards
06-12-2009 1:03 PM |
Sure. You can think of IsolatedStorage as a virtual file system. You have access to primitives like CreateDirectory(), DirectoryExists(), CreateFile(), etc. When you call CreateFile(), it will return a Stream to you. Just write the zip content to the Stream provided, and close it afterwards. I don't use SharpZipLib but I assume the constructor of the ZipStream has a stream argument, and you want to pass in the stream returned by IsolatedStorage as the argument.
Some pseudo code:
IsolatedStorage store;if (!store.DirectoryExists("Media")) store.CreateDirectory("Media");if (store.FileExists("Media/" + filename)) sotre.DestroyFile("Media/" + filename);Stream stream = store.CreateFile("Media/" + filename);if (stream == null) throw new Exception();ZipStream zs = new ZipStream(stream); // ... whatever signature ...zs.Write(bytes, 0, bytes.Length);zs.Close();stream.Close();
06-13-2009 6:31 PM |
Hi, Can you please have a look on my code and help me to find what I am doing wrong.
filebuffer =
fileStream.Close();
fileStream.Dispose();
zs.Write(filebuffer, 0, filebuffer.Length);
isolatedStorageFileStream.Close();
isolatedStorageFileStream.Dispose();
zs.Close();
isolatedStorageFile.Dispose();---------------------------------------------------------------------------
commented line copy the actual file in isolated storage and works fine I commented that line and trying to read the stream in zipoutputstream but it i see exception on line zs.Write(......) "NO OPEN ENTRY"
06-13-2009 10:21 PM |
I don't use SharpZipLib so I don't know the syntax. I do recommend you first try to write to and read from a MemoryStream just so that the problem is not with IsolatedStorage.
06-15-2009 9:37 AM |
i tried with memory stream and i sitll see the same error. Can anyone please help me to figure out why sharp zip lib raising this error "No open entry.".
Mog Lian...
Star
14812 points
1,417 Posts
06-16-2009 11:49 PM |
You need create ZipEntry for each file in zip file.
I wrote a sample to test compress and decompress image, then display.
private void Button_Click(object sender, RoutedEventArgs e) { var ofd1 = new OpenFileDialog(); var result = ofd1.ShowDialog(); if (result.HasValue && result.Value) { //read file to byte[] Stream fileStream = ofd1.File.OpenRead(); var filebuffer = new byte[(int)fileStream.Length]; fileStream.Read(filebuffer, 0, (int)fileStream.Length); fileStream.Close(); fileStream.Dispose(); //create isolatedstorage file var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication(); var filestream2 = isolatedStorageFile.CreateFile(ofd1.File.Name+".zip"); //zip var zs = new ZipOutputStream(filestream2); var entry = new ZipEntry(ofd1.File.Name); zs.PutNextEntry(entry); zs.Write(filebuffer, 0, filebuffer.Length); zs.CloseEntry(); zs.Close(); filestream2.Close(); filestream2.Dispose(); //get isolatedstorage file var filestream3 = isolatedStorageFile.OpenFile(ofd1.File.Name + ".zip", FileMode.Open); //unzip byte[] buff1 = new byte[1024]; var memstream1 = new MemoryStream(); var zis = new ZipInputStream(filestream3); zis.GetNextEntry(); int readlength=0; while (true) { readlength = zis.Read(buff1, 0, buff1.Length); memstream1.Write(buff1, 0, readlength); if (readlength <= 0) break; } //display var bitmap1 = new BitmapImage(); bitmap1.SetSource(memstream1); img1.Source = bitmap1; } }
06-17-2009 12:25 AM |
Hi Mog Liang,
Thanks for sharing the code, yes it works. However I found following issues, can you please help me out for these issues as well:
1) I used your given code and it took 2 minutes 25 seconds to compress an audio file size 8.22 Mb, only addition in my code was I set zipoutputstream.SetLevel(9) , I wanted to make maximum compressed file.
2) In silvelright after user select a file in open file dilaouge it keep the dilaouge showing while compression routine is running, it shows kind of stuck, how can I update the look and give message to user "compressing...." i tried but as soon compression code starts it stucks until compression is done.
3) is there anyway to get a compressed stream in byte array, wihtout reading it again from stored place ?
06-17-2009 2:37 AM |
For 1st question, based on my test, write isolatedstorage file cost up to 90% time, compress and decompress only cost about 7% time, so if you use memorystream instead of isolatedstoragefilestream, the process will speed up 10 times
For second question, try use BackgroundWorker to run compression on other thread.
my code.
FileInfo _fileinfo; private void Button_Click(object sender, RoutedEventArgs e) { var ofd1 = new OpenFileDialog(); var result = ofd1.ShowDialog(); if (result.HasValue && result.Value) { tb1.Text = "Compressing..."; _fileinfo = ofd1.File; BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); bw.RunWorkerAsync(); } } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //tb1.Text = "Compression complete."; } void bw_DoWork(object sender, DoWorkEventArgs e) { DateTime starttime = DateTime.Now; string timestring=""; //read file to byte[] Stream fileStream = _fileinfo.OpenRead(); var filebuffer = new byte[(int)fileStream.Length]; fileStream.Read(filebuffer, 0, (int)fileStream.Length); fileStream.Close(); fileStream.Dispose(); timestring += "read file stream: " + (DateTime.Now - starttime).TotalMilliseconds; starttime = DateTime.Now; //create isolatedstorage file var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication(); var filestream2 = isolatedStorageFile.CreateFile(_fileinfo.Name + ".zip"); timestring += "\ncreate isolatedstorage file: " + (DateTime.Now - starttime).TotalMilliseconds; starttime = DateTime.Now; //zip var zs = new ZipOutputStream(filestream2); var entry = new ZipEntry(_fileinfo.Name); zs.PutNextEntry(entry); zs.Write(filebuffer, 0, filebuffer.Length); zs.CloseEntry(); zs.Close(); filestream2.Close(); filestream2.Dispose(); timestring += "\nzip and write isolatedstoreage file: " + (DateTime.Now - starttime).TotalMilliseconds; starttime = DateTime.Now; //get isolatedstorage file var filestream3 = isolatedStorageFile.OpenFile(_fileinfo.Name + ".zip", FileMode.Open); //unzip byte[] buff1 = new byte[1024]; var memstream1 = new MemoryStream(); var zis = new ZipInputStream(filestream3); zis.GetNextEntry(); int readlength = 0; while (true) { readlength = zis.Read(buff1, 0, buff1.Length); memstream1.Write(buff1, 0, readlength); if (readlength <= 0) break; } timestring += "\nunzip file: " + (DateTime.Now - starttime).TotalMilliseconds; starttime = DateTime.Now; //display. //use Dispather switch to UI thread. Dispatcher.BeginInvoke(delegate { var bitmap1 = new BitmapImage(); bitmap1.SetSource(memstream1); img1.Source = bitmap1; tb1.Text = timestring; }); }
For 3rd question, you can use MemoryStream.
06-17-2009 3:49 AM |
Is this code built on SL2 or SL3? A while ago I reported an IsolatedStorage write performance bug, and it was mentioned that this will be fixed in SL3, although I haven't tested it as I dealt with it using the "workaround" already. The zip package may very well exercise the same performance problem.
See this thread http://silverlight.net/forums/p/75315/180892.aspx
06-17-2009 9:11 AM |
many thanks for code samples and guidance, I just tried it with memory stream and it still takes same amount of time to zip. May be i am doing something wrong, can you please update your snippet doing it with memory stream, that will makes me clear if i am suing memory stream in right way or not.
Best regards
06-17-2009 10:29 PM |
my code, compress 6MB wma file spend 2 seconds
private MemoryStream CompressFile(FileInfo inputfile) { FileStream inputstream = inputfile.OpenRead(); MemoryStream stream1 = new MemoryStream(); ZipOutputStream stream2 = new ZipOutputStream(stream1); //read file byte[] buffer1 = new byte[(int)inputstream.Length]; inputstream.Read(buffer1, 0, (int) inputstream.Length); inputstream.Close(); inputstream.Dispose(); //compress ZipEntry entry = new ZipEntry(inputfile.Name); stream2.PutNextEntry(entry); stream2.Write(buffer1, 0, buffer1.Length); stream2.CloseEntry(); stream1.Flush(); return stream1; }
06-17-2009 10:33 PM |
That's way too long to zip. Perhaps you wanna look at ZipForge which is another zip package. I have no issue with it. Perhaps more efficient than SharpZipLib?
06-18-2009 8:13 AM |
one critical issue i am unable to figure out so far is follwoing exception. my requirments are like, I zip a file in silverlight component and later i have to read that file for my java applet. when we try to open file in java following exception occur.
Exception in thread "main" java.util.zip.ZipException: invalid entry size (expected 4294967295 but got 8628524 bytes)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:373)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:141)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:105)
why header is incorrect ??
06-18-2009 8:56 AM |
in above mentioned code if you add following 2 lines, you will not get exception if you trying to unzip file in java
zipEntry.Size = actualfilebufer.Length;
SaurabhAgg
6 points
3 Posts
07-01-2009 9:38 AM |
@Mog Liang
I couldn't find any ZipOutputStream class for Silverlight, is this from vjslib.dll ?
If yes, then is there any way we can create a zip of a folder in Silverlight ?
Thanks.
-Saurabh
07-01-2009 9:47 AM |
have a look on this thread, hope it will help
http://silverlight.net/forums/t/21392.aspx
07-01-2009 10:00 AM |
Thanks for the quick reply .. actually what I want to do is that I have some folders & files which I want to be packaged in a zip file. Using SharpZipLib, I guess we can just compress a single file, and that too can't be read using winzip / winrar.
07-01-2009 10:12 AM |
ok then try this one, this should help
http://www.eggheadcafe.com/tutorials/aspnet/d566463d-83bd-486a-8633-53aa54f405bf/silverlight-2-beta-2-doi.aspx
07-01-2009 10:56 AM |
I'm not sure if I'm missing on to something, but even this won't allow me to compress a folder with files that can be read using winzip / winrar (saw this in the comments).