Zipfile as Stream, then add files into stream, then convert to byte array

Jul 25, 2008 at 2:32 AM
Ok, sorry if this post is a dupe from somewhere else. I tried searching for what I was looking to do, but I couldn't find it.  I reviewed the following two posts, but they didn't seem to help...
Support for MemoryStreams
Save ZipFile to MemoryStream, but then the MemoryStream is not readable

I have a function that I want to take an array of bytes, the filename to create inside the zip file stream, and the password. I want it to them return the byte array of the zipfile so I can save it out to the filesystem or store it in a database as necessary.  The code below isn't working. I have tried multiple variations, but this one gets me the closest.  Essentially I want to create a zip file in a memory stream, then add the file (indicated by the byte() array sent to the function) using the AddFileStream function, then write that new zip file stream with the file in it with the zipped password out to an array of bytes and return that from the function. Any ideas on what I am doing wrong?  Any help would be greatly appreciated. Thanks!

 

Public Function Compress(ByVal oBytes As Byte(), ByVal sFilename As String, ByVal sPassword As String) As Byte()
Dim oCompressedStream As New System.IO.MemoryStream()
Dim oOriginalStream As New System.IO.MemoryStream(oBytes.Length - 1)
oOriginalStream.Write(oBytes, 0, oBytes.Length)
Dim iCompressor As New Ionic.Utils.Zip.ZipFile(oCompressedStream)
iCompressor.Password = sPassword
iCompressor.Save()
iCompressor.AddFileStream(sFilename,
"", oOriginalStream)
iCompressor.Save()
Dim oReturnBytes(oCompressedStream.Length - 1) As Byte
oCompressedStream.Position = 0
oCompressedStream.Read(oReturnBytes, 0, oCompressedStream.Length)
Dim oStream As IO.FileStream = IO.File.Create("c:\t2.zip")
oStream.Read(oReturnBytes, 0, oReturnBytes.Length)
oStream.Close()
oOriginalStream.Close()
iCompressor =
Nothing
oOriginalStream = Nothing
oCompressedStream = Nothing
Return oReturnBytes
End Function

 

Coordinator
Jul 28, 2008 at 10:57 PM

I think you want to reset the position of the oOriginalStream after you write it, and before you read it.  The ZipFile class reads the stream when you call .Save().  The ZipFile class will not reset the position of the streams it compresses before reading them.   The caller is responsible for that. 

    Public Function Compress(ByVal oBytes As Byte(), ByVal sFilenameInArchive As String, ByVal sPassword As String, ByVal sZipFile As String ) As Byte()
        Dim oCompressedStream As New System.IO.MemoryStream()

        Dim oOriginalStream As New System.IO.MemoryStream(oBytes.Length - 1)
        oOriginalStream.Write(oBytes, 0, oBytes. Length)
        oOriginalStream.Seek(System.IO.SeekOrigin.Begin, 0)

        Try 
            Using zip As New ionic.Utils.Zip.ZipFile(oCompressedStream)
                zip.Password = sPassword
                zip.AddFileStream(sFilenameInArchive, "", oOriginalStream)
                zip.Save()
            End Using
        Catch ex1 As Exception
            Console.Error.WriteLine("exception: " & ex1.ToString())
        End Try

        Dim oReturnBytes(oCompressedStream.Length - 1) As Byte
        oCompressedStream.Position = 0
        oCompressedStream.Read(oReturnBytes, 0, oCompressedStream.Length)
        Using oStream As System.IO.FileStream = IO.File.Create(sZipFile)
            oStream.Write(oReturnBytes, 0, oReturnBytes.Length)
            oStream.Close()
        End Using 
        oOriginalStream.Close()

        Return oReturnBytes

    End Function 
Jul 30, 2008 at 12:38 AM
Ahh, ok, that seems to work. Thanks!  I still have two problems though. First, I can't seem to just save the stream out to a file myself without using
your save function? not sure why that would matter. Second, I want to extract a file that is password protected into a stream. I can't figure
that one out? I can read the zipfile from the stream, but not extract the file into a stream.  Any suggestions?
Coordinator
Jul 30, 2008 at 5:10 PM
Edited Aug 8, 2008 at 4:20 AM
ah, I don't know what you mean.  "I can't seem to just save the stream out to a file myself without using
your save function?"  Why do you want to save it without calling Save().  I don't understand.   The way the library works is,
if you want to save the archive, you call Save().  I am sure I am misunderstanding something.

I also don't know what you mean by 
"Second, I want to extract a file that is password protected into a stream. "

did you look at the ZipEntry.OpenReader() methods?