/// <summary> /// Add a new entry to the zip /// </summary> /// <param name="entry"> /// The details about the header of the entry /// </param> public void Add(ZipEntry entry) { FileStream fs = null; fs = File.OpenRead(entry.Name); entry.Size = (Int32)fs.Length; entry.DateTime = File.GetLastWriteTime(entry.Name); PutNextHeader(entry); WriteCompressedFile(fs, entry); }
/// <summary> /// Extracts the specified entry /// </summary> /// <param name="entry"> /// The entry that is to be extracted.Cannot be null /// </param> /// <param name="jump"> /// The offset from the SeekOrigin.Begin at which the /// comrpessed data is located /// </param> public void Extract(ZipEntry entry, long jump, string startPath) { DirectoryInfo dir = new DirectoryInfo(startPath + zipName); if (!dir.Exists) dir.Create(); int index1 = entry.Name.IndexOf(ZipConstants.BackSlash); int index2 = entry.Name.LastIndexOf(ZipConstants.BackSlash); string relPath = entry.Name.Substring(index1 + 1, index2 - index1); if (index1 == 0) relPath = String.Empty; if (relPath.Length != 0) dir.CreateSubdirectory(relPath); baseStream.Seek(jump, SeekOrigin.Begin); jump = ZipConstants.FixedHeaderSize + entry.NameLength; baseStream.Seek(jump, SeekOrigin.Current); WriteUncompressedFile(entry, startPath + zipName + ZipConstants.BackSlash + relPath); }
private void WriteCompressedSizeCRC(Int32 value, byte[] crc, ZipEntry entry) { entry.CompressedSize = value; entry.SetCrc(crc); baseStream.Seek(offset, SeekOrigin.Begin); WriteLeInt32(entry.CompressedSize); WriteBytes(crc); //Remove the recorded offset offset = -1; baseStream.Seek(0, SeekOrigin.End); }
/// <summary> /// Writes the compressed data into the basestream /// It instantiates a memory stream which will serve /// as a temp store and then compresses it using Gzip Stream or /// Deflate stream and writes it to the base stream /// </summary> private void WriteCompressedFile(FileStream fStream, ZipEntry entry) { using (MemoryStream ms = new MemoryStream()) { if (method == ZipConstants.DEFLATE) zipStream = new DeflateStream(ms, CompressionMode.Compress, true); else if (method == ZipConstants.GZIP) zipStream = new GZipStream(ms, CompressionMode.Compress, true); byte[] buffer = new byte[fStream.Length]; fStream.Read(buffer, 0, buffer.Length); zipStream.Write(buffer, 0, buffer.Length); zipStream.Close(); byte[] b = new byte[ms.Length]; ms.Seek(0, SeekOrigin.Begin); ms.Read(b, 0, b.Length); baseStream.Write(b, 0, b.Length); //Go back and write the length and the CRC WriteCompressedSizeCRC((int)ms.Length, ComputeMD5(b), entry); } }
/// <summary> /// Puts the next header in a predefined order /// </summary> /// <param name="entry"> /// the ZipEntry which contains all the information /// </param> private void PutNextHeader(ZipEntry entry) { WriteLeInt32(entry.Size); //REcord the offset to write proper CRC and compressed size offset = baseStream.Position; WriteLeInt32(entry.CompressedSize); WriteBytes(entry.GetCrc()); WriteLeInt32(entry.DosTime); WriteLeInt16(entry.NameLength); byte[] names = ConvertToArray(entry.Name); baseStream.Write(names, 0, names.Length); }
/// <summary> /// Remove an entry from the archive /// </summary> /// <param name="jump"> /// The offset of the file to be removed /// </param> public void Remove(long jump, ZipEntry entry) { long fileJump = ZipConstants.FixedHeaderSize + entry.NameLength + entry.CompressedSize; baseStream.Seek(jump + fileJump, SeekOrigin.Begin); long length = baseStream.Length - fileJump - jump; byte[] b = new byte[length]; baseStream.Read(b, 0, (int)length); baseStream.Seek(jump, SeekOrigin.Begin); baseStream.Write(b, 0, (int)length); baseStream.SetLength(baseStream.Length - fileJump); }
/// <summary> /// Writes the uncompressed data into the filename in the /// entry. It instantiates a memory stream which will serve /// as a temp store and decompresses it using Gzip Stream or /// Deflate stream /// </summary> private void WriteUncompressedFile(ZipEntry entry, string completePath) { MemoryStream ms = new MemoryStream(); try { byte[] b = new byte[entry.CompressedSize]; baseStream.Read(b, 0, (int)entry.CompressedSize); if (CheckCRC(entry.GetCrc(), b)) ms.Write(b, 0, b.Length); ms.Seek(0, SeekOrigin.Begin); if (method == ZipConstants.DEFLATE) zipStream = new DeflateStream(ms, CompressionMode.Decompress, false); else if (method == ZipConstants.GZIP) zipStream = new GZipStream(ms, CompressionMode.Decompress, false); int index = entry.Name.LastIndexOf(ZipConstants.BackSlash); string name = completePath + entry.Name.Substring(index + 1); FileStream rewrite = new FileStream(name, FileMode.Create); b = new byte[entry.Size]; zipStream.Read(b, 0, (int)entry.Size); rewrite.Write(b, 0, (int)entry.Size); rewrite.Close(); } finally { zipStream.Close(); ms.Close(); } }
/// <summary> /// Open the next entry from the zip archive, and return its /// description. The method expects the pointer to be intact. /// </summary> private ZipEntry GetNextEntry() { ZipEntry currentEntry = null; Int32 size = ReadLeInt32(); if (size == -1) return new ZipEntry(String.Empty); Int32 csize = ReadLeInt32(); byte[] crc = new byte[16]; ReadBuf(crc, crc.Length); Int32 dostime = ReadLeInt32(); Int16 nameLength = ReadLeInt16(); byte[] buffer = new byte[nameLength]; ReadBuf(buffer, nameLength); string name = ConvertToString(buffer); currentEntry = new ZipEntry(name); currentEntry.Size = size; currentEntry.CompressedSize = csize; currentEntry.SetCrc(crc); currentEntry.DosTime = dostime; return currentEntry; }
public void Add(string fileName) { ZipEntry entry = new ZipEntry(fileName); thisWriter.Add(entry); zipEntries.Add(entry); thisWriter.CloseHeaders((Int16)zipEntries.Count); }