How to match my zip to WinZip's zip?

Apr 18, 2010 at 11:59 AM

How to match my zip file to be exact like the one created with WinZip?

I create my zip in memory with items that are in memory as well. I use AddEntry for this. My zip is to be unpacked with 3rd party software. This software complains that my zip is invalid, or that is unable to find some path within it. But if I repack my zip file to another with WinZip then the software does not complain to this repacked zip.

I found out that if I set EmitTimesInWindowsFormatWhenSaving value to false then 3rd party software "changes the tune", ie. it does not complain about zip file being invalid anymore, but it says that is now unable to find a directory inside it. I suspect on the following. When I inspect my zip with UnZip -i then I see that there are no entries for partial folders paths. Those entries can be found in WinZip's zip file.

Is there a way to tell the library to add those "partial subfolders" entries automatically when I add an entry with a path?

Are there other settings that would make my zip as close as possible to WinZip's zip?

Coordinator
Apr 21, 2010 at 4:01 PM

You can add directories explicitly, with ZipFile.AddDirectoryByName().

I guess what you could do is this:  for each entry added, you'd have to check if the containing directory exists in the zip file, then add it as necessary.

 

May 4, 2010 at 12:28 PM

Sorry for not replying sooner. Here's working code. This code implies that programmer has to know how partial directories are stored in inner dictionary. Is there a reason for not having a function AddFile(byte[] fileContent, String filePathInArchive)?

using (ZipFile zip = new ZipFile())
{
	zip.EmitTimesInUnixFormatWhenSaving = false;
	zip.EmitTimesInWindowsFormatWhenSaving = false;

	byte[] fileContent;
	String directory;
	String imageName;
	
	...
	
	// Add missing partial directories
	String[] dirParts = directory.Split(
		new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
	String dirCurrent = "";

	for (int dirIndex = 0; dirIndex < dirParts.Length; ++dirIndex)
	{
		dirCurrent += dirParts[dirIndex] + "/";

		if (!zip.ContainsEntry(dirCurrent))
			zip.AddDirectoryByName(dirCurrent);
	}

	// Add file
	zip.AddEntry(directory + "/" + fileName, fileContent);
}

Coordinator
May 4, 2010 at 1:28 PM
Dialecticus wrote:

Is there a reason for not having a function AddFile(byte[] fileContent, String filePathInArchive)?

I don't understand. You have the AddEntry() method that accepts those argument types, right? Are you asking, why is the method called "AddEntry" as opposed to "AddFile"? The reason is it isn't a file you're adding, it's an entry in the zip. Really, the AddFile method should be named AddEntryFromFile, but I can't change that now.  

May 4, 2010 at 3:24 PM

I assumed, erroneously apparently, that AddFile function actually adds missing partial directories into zip. Well, if nobody else is complaining then current solution is good enough for me.

Coordinator
May 5, 2010 at 12:22 AM

No, AddFile doesn't add a directory tree.  There's no method that does that. 
There's AddDirectoryByName, if you want to explicitly insert a single directory entry into the zip file.