Can anyone tell me why the following code doesnt work? I am using the SharpZipLib API for the Zip streams, latest version DL'ed today from their site. Im attempting to use this logic to merge the contents of one zip file into another, without having to perform IO on the disk, as the intended zip files may contain reserved file names for windows. I have tried this with multiple different source and destination zip files (those that contain reserved names and those that dont). The code does not throw any exception, and if you inspect the buffer prior to each write operation, you can see that it contains real data, yet after the entire operation finishes the size of the target zip file has not changed, and you can explore it to confirm that no new files (the ones the code is supposed to add) have actually been added to the destination file. :(

It gets around the file name problem by using a temp file (tmp.tmp) in a given directory, then giving the file the original name in the archive
–
Mark WAug 8 '12 at 5:07

Your code will work fine, but .. I have a couple notes for you. 1. your code saves the output file once for each entry that gets added. this is unnecessary. 2. You can avoid the writing to the filesystem entirely. see my answer for details.
–
CheesoOct 30 '12 at 17:58

I had to call the save there :(. During my tests, when i queued up the list of files to add and tried to add them all at once, with a single call to to the Save() method, for whatever reason, the file remained unchanged. I am well aware of the giagantic performance hit I took saving where I do, but unfortunately I couldnt make it work the appropriate way.
–
Mark WNov 5 '12 at 19:15

I've followed those examples to create the code that I posted here. At this point it doesnt matter if it overwrites or not, the above code doesnt change the state of the destination zip file at all. If it was overwriting, at least I would have something to debug... I dont need to use a memeory stream. What I mean by 'without using the disk' is that I cant extract the contents of one zip onto the hard drive, then repack it into another zip. It has to move from one zip to the next without being unpacked on the HD because of windows file naming conventions.
–
Mark WAug 7 '12 at 21:38

I used new FileStream(outArchive, FileMode.Open) inplace of File.OpwnWrite(). It didnt change the result at all.
–
Mark WAug 7 '12 at 21:45

This approach uses the ZipFile.AddEntry overload that accepts two delegates: an opener and a closer. These functions get called at the time of ZipFile.Save. The former delegate needs to open and return the stream that contains the data to be zipped. The latter delegate needs to just close the stream.

It is necessary to define the getInStreamReturner Func , in order to open the right stream at the time of ZipFile.Save. Bear in mind that the zipEntryName changes value each time through the loop. Also ZipEntry.OpenReader() opens a stream on the actual zip data, which reads-and-decompresses as it goes. You can have only one of those open, at any one time, per ZipFile. getInStreamReturner creates a new function each time through the loop, thereby creating a closure to retain the value of the zipEntryName for reference at the time of ZipFile.Save.

This approach will fail if there are name clashes between the inArchive and outArchive. To avoid that you'd need to check for that and somehow avoid it. Either contrive a new, unique name, or skip adding entries with duplicate names into the outarchive.

I haven't tested this.

While this approach does not write to the filesystem, it does decompress and recompress file data. There is an open request to provide a feature to DotNetZip to migrate entries without that decompress/recompress jump. I haven't implemented that yet.