Problem with AddFileFromString

Mar 3, 2009 at 10:09 AM
Hi, I've problem when I save compress file on steam, this is a simple code to reproduce the issue:

        'Save to stream
        Using zip As New Ionic.Zip.ZipFile
            zip.AddFileFromString("file.zip", "", System.IO.File.ReadAllText("c:\temp\test.html"))
            Dim s As New System.IO.MemoryStream()
            zip.Save(s)
            System.IO.File.WriteAllText("c:\temp\test.html_1.zip", System.Text.Encoding.Default.GetString(s.ToArray))
        End Using

        'Save to file
        Using zip As New Ionic.Zip.ZipFile
            zip.AddFile("c:\temp\test.html", "")
            zip.Save("c:\temp\test.html_2.zip")
        End Using

The test.html_1.zip seems corrupted and it's also twice bigger then test.html_2.zip..
Coordinator
Mar 3, 2009 at 3:12 PM
Edited Mar 5, 2009 at 5:23 PM
Hmmmm, yes I would bet you have experienced a few problems!
 
First, what do you expect to get when calling System.Text.Encoding.Default.GetString() using s.ToArray() as the input?     The zip data contained within s.ToArray() is not an encoded string.  Calling GetString() on it will not produce a usable string; I suspect if you print out the result of that call, you will get a long series of question marks.  And then, writing that string (?????????????????????????) out to a file will not produce a valid zip file. It is just a series of question marks.

What are you trying to accomplish, with that code? Can you explain in english?

Next - the MemoryStream is disposable, and should be wrapped in a using clause.

This code will save a zip to a MemoryStream and then writes the content of that MemoryStream to a disk file. Notice there is no attempt to decode the zip file data into a string  with a call to Encoding.GetString().
Dim buffer As Byte() = Nothing
' This will not scale very well!
Using ms As MemoryStream = New MemoryStream
    Using zip As ZipFile = New ZipFile
        zip.AddItem(NameOfFileOrDirectoryToZip)
        zip.Save(ms)
    End Using
    buffer = ms.ToArray
End Using

Using output As FileStream = File.Create(archiveName)
    output.Write(buffer, 0, buffer.Length)
End Using

But that approach is not very scalable. Suppose you have a zip file that is 1mb in size. Then you will have a 1mb buffer in memory. Large, but not too large. Now suppose you have a 2gb zip file. Will you retain a 2gb buffer in memory?  This approach works for small zip files but doesn't scale up well.
The DotNetZip library can save zip files into a stream, or it can save to a file on disk.  You seem to be doing something in the middle - you write the data to a stream and then write it to a file. 
What is it that you really want to do? What are you trying to accomplish?

There is a third problem in your code, something I don't understand at all.  You have this code:
zip.AddFileFromString("file.zip", "", System.IO.File.ReadAllText("c:\temp\test.html"))

This statement adds a new entry into the ZipFile instance; the entry is named "file.zip". And the contents of that entry are obtained from a file called "c:\temp\test.html". This does not make sense to me, for a couple reasons. First, you are inserting what is apparently an HTML file into an entry named "file.zip". As above, using the .zip extension does not make it a zip file.  This is very confusing to me.  The content is still going to be HTML. Second, why use AddFileFromString() when the entry you want to add to the zip file, is in a file already? Why not just call AddFile? This would be more sensible, to me:
zip.AddFile("c:\temp\test.html")

With that line of code, you are telling DotNetZip to add a file ("c:\temp\test.html") to the ZipFile instance.  
Regarding that call to AddFileFromString(), I will ask the same question I asked above: what are you trying to accomplish?
Have you read the documentation for DotNetZip? I've tried to be very thorough with it.