none
how to compress file!

    Question

  • 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

    Thursday, June 11, 2009 5:02 PM

Answers

  • 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;
                }
            }
     
    Tuesday, June 16, 2009 11:49 PM
  • 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.

    Wednesday, June 17, 2009 2:37 AM
  • 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;
        }
     
    Wednesday, June 17, 2009 10:29 PM
  • in above mentioned code if you add following 2 lines, you will not get exception if you trying to unzip file in java

    zipEntry.CompressionMethod = CompressionMethod.Deflated;

    zipEntry.Size = actualfilebufer.Length;

     

    Regards

    Thursday, June 18, 2009 8:56 AM

All replies

  • 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)!

    Thursday, June 11, 2009 5:21 PM
  • 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?

    Regards

    Friday, June 12, 2009 3:53 AM
  • SharpZipLib is probably a WPF application in its packaged form.  You need to create a SL library, add files, and compile.
    Friday, June 12, 2009 4:06 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

    Friday, June 12, 2009 7:35 AM
  • 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();
      
    Friday, June 12, 2009 1:03 PM
  • Hi, Can you please have a look on my code and help me to find what I am doing wrong.

    Stream fileStream = openFileDialog1.File.OpenRead();

    filebuffer = new byte[(int)fileStream.Length];

    fileStream.Read(filebuffer, 0, (int)fileStream.Length);

    fileStream.Close();

    fileStream.Dispose();

     

    var isolatedStorageFileStream = new IsolatedStorageFileStream("\\MyAppFolder\\" + openFileDialog1.File.Name, FileMode.Create, isolatedStorageFile);

    //isolatedStorageFileStream.Write(filebuffer, 0, filebuffer.Length);

    var zs = new ZipOutputStream(isolatedStorageFileStream);

    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"

    Regards

    Saturday, June 13, 2009 6:31 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.
    Saturday, June 13, 2009 10:21 PM
  • 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.".

    Monday, June 15, 2009 9:37 AM
  • 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;
                }
            }
     
    Tuesday, June 16, 2009 11:49 PM
  • 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 ?

     Regards

     

    Wednesday, June 17, 2009 12:25 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.

    Wednesday, June 17, 2009 2:37 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

    Wednesday, June 17, 2009 3:49 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

    Wednesday, June 17, 2009 9:11 AM
  • 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;
        }
     
    Wednesday, June 17, 2009 10:29 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?
    Wednesday, June 17, 2009 10:33 PM
  • 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 ??

    Thursday, June 18, 2009 8:13 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.CompressionMethod = CompressionMethod.Deflated;

    zipEntry.Size = actualfilebufer.Length;

     

    Regards

    Thursday, June 18, 2009 8:56 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

    Wednesday, July 01, 2009 9:38 AM
  • have a look on this thread, hope it will help

     http://silverlight.net/forums/t/21392.aspx

    Wednesday, July 01, 2009 9:47 AM
  • Thanks for the quick reply Smile.. 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.

     

    Thanks.

    Wednesday, July 01, 2009 10:00 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).

     

    Thanks.

    Wednesday, July 01, 2009 10:56 AM