Here is the code I use to write a file to a ZIP file:
Private ZipToWrite As ZipOutputStream
Private Crc As New Crc32
Private Sub CreateZip(ByVal fname As String)
ZipToWrite = New ZipOutputStream(File.Create(fname))
ZipToWrite.SetLevel(9) ' 9 = maximum compression
End Sub
Private Sub CloseZip()
ZipToWrite.Finish()
ZipToWrite.Close()
End Sub
Private Sub WriteFileToZip(ByVal fname As String, ByVal basepath As String)
Dim strmFile As FileStream = File.OpenRead(fname)
Dim abyBuffer(strmFile.Length - 1) As Byte
strmFile.Read(abyBuffer, 0, abyBuffer.Length)
Dim objZipEntry As ZipEntry
If basepath.Length <> 0 Then
objZipEntry = New ZipEntry(fname.Replace(basepath, String.Empty).ToLower)
Else
objZipEntry = New ZipEntry(fname.ToLower)
End If
objZipEntry.DateTime = DateTime.Now
objZipEntry.Size = strmFile.Length
strmFile.Close()
Crc.Reset()
Crc.Update(abyBuffer)
objZipEntry.Crc = Crc.Value
ZipToWrite.PutNextEntry(objZipEntry)
ZipToWrite.Write(abyBuffer, 0, abyBuffer.Length)
End Sub
The purpose of the
basepath
parameter is so that you can ZIP up a folder and have the folder name magically go away.Mind you, some ZIP utilities, when unzipping multiple folders, expect a directory entry for that folder...and if they don't find the directory entry, they'll crash out or say that your ZIP file is corrupt. In that case, before you add the first file for a subdirectory, add in a 0-byte file with this sub...
Private Sub WriteZeroByteFileToZip(ByVal fname As String, ByVal basepath As String)
Dim abyBuffer(0) As Byte
Dim objZipEntry As ZipEntry
If basepath.Length <> 0 Then
objZipEntry = New ZipEntry(fname.Replace(basepath, String.Empty).ToLower & "\")
Else
objZipEntry = New ZipEntry(fname.ToLower & "\")
End If
objZipEntry.DateTime = DateTime.Now
objZipEntry.Size = 0
Crc.Reset()
Crc.Update(0)
objZipEntry.Crc = Crc.Value
ZipToWrite.PutNextEntry(objZipEntry)
End Sub
I hope that helps.
6 comments:
This sounds good, but do you also have sample code on how to add a file to an existing zip file?
Thanks for the posting. Here's a C# translation:
private ZipOutputStream ZipToWrite;
private Crc32 Crc = new Crc32();
private void CreateZip(string ZipFilename)
{
ZipToWrite = new ZipOutputStream(File.Create(ZipFilename));
ZipToWrite.SetLevel(9); // 9 = maximum compression
}
private void CloseZip()
{
ZipToWrite.Finish();
ZipToWrite.Close();
}
private void WriteFileToZip(string Filename, string BasePath)
{
FileStream strmFile = File.OpenRead(Filename);
byte[] abyBuffer = new byte[strmFile.Length - 1];
strmFile.Read(abyBuffer, 0, abyBuffer.Length);
ZipEntry objZipEntry;
if (BasePath.Length > 0)
objZipEntry = new ZipEntry(Filename.Replace(BasePath, String.Empty).ToLower);
else
objZipEntry = new ZipEntry(Filename.ToLower);
objZipEntry.DateTime = DateTime.Now;
objZipEntry.Size = strmFile.Length;
strmFile.Close();
Crc.Reset();
Crc.Update(abyBuffer);
objZipEntry.Crc = Crc.Value;
ZipToWrite.PutNextEntry(objZipEntry);
ZipToWrite.Write(abyBuffer, 0, abyBuffer.Length);
}
I found an implementation of Crc32 here: http://staceyw.spaces.live.com/blog/cns!F4A38E96E598161E!402.entry
Thanks! You helped us fix an issue with the windows zip utility because we weren't adding the empty folder entries to the zip file.
I overloaded your method to split the filename and path from the fullname. It calls your other method:
private void WriteFileToZip(string FilePathAndName)
{
string BasePath = System.IO.Path.GetDirectoryName(FilePathAndName).ToString();
string FileName = System.IO.Path.GetFileName(FilePathAndName).ToString();
WriteFileToZip(Filename, BasePath);
}
Post a Comment