/// <inheritdoc cref="Finish"/>> public override async Task FinishAsync(CancellationToken ct) { using (var ms = new MemoryStream()) { if (entries == null) { return; } if (curEntry != null) { await CloseEntryAsync(ct); } long numEntries = entries.Count; long sizeEntries = 0; foreach (var entry in entries) { await baseOutputStream_.WriteProcToStreamAsync(ms, s => { sizeEntries += ZipFormat.WriteEndEntry(s, entry, _stringCodec); }, ct); } await baseOutputStream_.WriteProcToStreamAsync(ms, s => ZipFormat.WriteEndOfCentralDirectory(s, numEntries, sizeEntries, offset, zipComment), ct); entries = null; } }
/// <inheritdoc cref="CloseEntry"/> public async Task CloseEntryAsync(CancellationToken ct) { await baseOutputStream_.WriteProcToStreamAsync(WriteEntryFooter, ct); // Patch the header if possible if (patchEntryHeader) { patchEntryHeader = false; await ZipFormat.PatchLocalHeaderAsync(baseOutputStream_, curEntry, patchData, ct); } entries.Add(curEntry); curEntry = null; }
/// <summary> /// Closes the current entry, updating header and footer information as required /// </summary> /// <exception cref="ZipException"> /// Invalid entry field values. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurs. /// </exception> /// <exception cref="System.InvalidOperationException"> /// No entry is active. /// </exception> public void CloseEntry() { WriteEntryFooter(baseOutputStream_); // Patch the header if possible if (patchEntryHeader) { patchEntryHeader = false; ZipFormat.PatchLocalHeaderSync(baseOutputStream_, curEntry, patchData); } entries.Add(curEntry); curEntry = null; }
public override FileFormat Match(FileFormatScanJob job) { if (!ValidateStartBytes(job)) { return(null); } if (!Validate(job)) { return(null); } var fingerprint = new ZipFormat(); return(fingerprint); }
/// <summary> /// Update Zip Comment /// Feature is supported in version 18.5 or greater of the API /// </summary> public static void UpdateComment() { try { using (ZipFormat format = new ZipFormat(Common.MapSourceFilePath(filePath))) { format.ZipInfo.Comment = "test comment"; //Or you can update it using ZipFileComment Property //format.ZipFileComment = "test comment"; format.Save(Common.MapDestinationFilePath(filePath)); } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
/// <summary> /// Removes comment in Zip file /// </summary> /// public static void RemoveComment() { try { //ExStart:RemoveCommentZIPFile_17.12 // initialize ZipFormat zipFormat = new ZipFormat(Common.MapSourceFilePath(filePath)); // remove user comment zipFormat.RemoveFileComment(); // and commit changes zipFormat.Save(); //ExEnd:RemoveCommentZIPFile_17.12 } catch (Exception exp) { Console.WriteLine(exp.Message); } }
/// <summary> /// Get Zip Metadata using stream /// Feature is supported in version 18.5 or greater of the API /// </summary> public static void GetZipMatadataUsingStream() { try { using (Stream stream = File.Open(Common.MapSourceFilePath(filePath), FileMode.Open, FileAccess.ReadWrite)) { using (ZipFormat format = new ZipFormat(stream)) { // get info ZipMetadata info = format.ZipInfo; // get total entries Console.WriteLine("Total Entries : {0}, ", info.TotalEntries); //get comments Console.WriteLine("Comments : {0}, ", info.Comment); foreach (var fileInfo in info.Files) { // get file name Console.WriteLine("File Name : {0}, ", fileInfo.Name); // get compressed size Console.WriteLine("CompressedSize : {0}, ", fileInfo.CompressedSize); // get uncompressed size Console.WriteLine("UncompressedSize : {0}, ", fileInfo.UncompressedSize); // get compression method Console.WriteLine("CompressionMethod : {0}, ", fileInfo.CompressionMethod); } } // The stream is still open here } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
/// <summary> /// Gets info of Zip file /// </summary> /// public static void GetZipMatadata() { try { //ExStart:GetZipMatadata // initialize using (ZipFormat zipFormat = new ZipFormat(Common.MapSourceFilePath(filePath))) { // get info ZipMetadata info = zipFormat.ZipInfo; // get total entries Console.WriteLine("Total Entries : {0}, ", info.TotalEntries); //get comments Console.WriteLine("Comments : {0}, ", info.Comment); foreach (var fileInfo in info.Files) { // get file name Console.WriteLine("File Name : {0}, ", fileInfo.Name); // get compressed size Console.WriteLine("CompressedSize : {0}, ", fileInfo.CompressedSize); // get uncompressed size Console.WriteLine("UncompressedSize : {0}, ", fileInfo.UncompressedSize); // get compression method Console.WriteLine("CompressionMethod : {0}, ", fileInfo.CompressionMethod); } } //ExEnd:GetZipMatadata } catch (Exception exp) { Console.WriteLine(exp.Message); } }
/// <summary> /// Finishes the stream. This will write the central directory at the /// end of the zip file and flush the stream. /// </summary> /// <remarks> /// This is automatically called when the stream is closed. /// </remarks> /// <exception cref="System.IO.IOException"> /// An I/O error occurs. /// </exception> /// <exception cref="ZipException"> /// Comment exceeds the maximum length<br/> /// Entry name exceeds the maximum length /// </exception> public override void Finish() { if (entries == null) { return; } if (curEntry != null) { CloseEntry(); } long numEntries = entries.Count; long sizeEntries = 0; foreach (var entry in entries) { sizeEntries += ZipFormat.WriteEndEntry(baseOutputStream_, entry, _stringCodec); } ZipFormat.WriteEndOfCentralDirectory(baseOutputStream_, numEntries, sizeEntries, offset, zipComment); entries = null; }
internal void PutNextEntry(Stream stream, ZipEntry entry, long streamOffset = 0) { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; // Check that the compression is one that we support if (method != CompressionMethod.Deflated && method != CompressionMethod.Stored) { throw new NotImplementedException("Compression method not supported"); } // A password must have been set in order to add AES encrypted entries if (entry.AESKeySize > 0 && string.IsNullOrEmpty(this.Password)) { throw new InvalidOperationException("The Password property must be set before AES encrypted entries can be added"); } int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Apply any required transforms to the entry name TransformEntryName(entry); // Write the local file header offset += ZipFormat.WriteLocalHeader(stream, entry, out var entryPatchData, headerInfoAvailable, patchEntryHeader, streamOffset, _stringCodec); patchData = entryPatchData; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; }