public Stream WriteToStream(string entryPath, ZipWriterEntryOptions options) { var compression = ToZipCompressionMethod(options.CompressionType ?? compressionType); entryPath = NormalizeFilename(entryPath); options.ModificationDateTime = options.ModificationDateTime ?? DateTime.Now; options.EntryComment = options.EntryComment ?? string.Empty; var entry = new ZipCentralDirectoryEntry(compression, entryPath, (ulong)streamPosition, WriterOptions.ArchiveEncoding) { Comment = options.EntryComment, ModificationTime = options.ModificationDateTime }; // Use the archive default setting for zip64 and allow overrides var useZip64 = isZip64; if (options.EnableZip64.HasValue) { useZip64 = options.EnableZip64.Value; } var headersize = (uint)WriteHeader(entryPath, options, entry, useZip64); streamPosition += headersize; return(new ZipWritingStream(this, OutputStream, entry, compression, options.DeflateCompressionLevel ?? compressionLevel)); }
public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions) { using (Stream output = WriteToStream(entryPath, zipWriterEntryOptions)) { source.TransferTo(output); } }
public Stream WriteToStream(string entryPath, ZipWriterEntryOptions options) { bool isDirectory = entryPath.EndsWith("/"); entryPath = NormalizeFilename(entryPath); if (isDirectory) { entryPath += "/"; } options.ModificationDateTime = options.ModificationDateTime ?? DateTime.Now; options.EntryComment = options.EntryComment ?? string.Empty; var entry = new ZipCentralDirectoryEntry { Comment = options.EntryComment, FileName = entryPath, ModificationTime = options.ModificationDateTime, HeaderOffset = (uint)streamPosition }; var headersize = (uint)WriteHeader(entryPath, options); streamPosition += headersize; return(new ZipWritingStream(this, OutputStream, entry, ToZipCompressionMethod(options.CompressionType ?? compressionType), options.DeflateCompressionLevel ?? compressionLevel)); }
private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64) { // We err on the side of caution until the zip specification clarifies how to support this if (!OutputStream.CanSeek && useZip64) { throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams"); } var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType); byte[] encodedFilename = WriterOptions.ArchiveEncoding.Encode(filename); Span <byte> intBuf = stackalloc byte[4]; BinaryPrimitives.WriteUInt32LittleEndian(intBuf, ZipHeaderFactory.ENTRY_HEADER_BYTES); OutputStream.Write(intBuf); if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate) { if (OutputStream.CanSeek && useZip64) { OutputStream.Write(stackalloc byte[] { 45, 0 }); //smallest allowed version for zip64
private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions) { var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType); byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename); OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate) { OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible } else { OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA } HeaderFlags flags = ArchiveEncoding.Default == Encoding.UTF8 ? HeaderFlags.UTF8 : 0; if (!OutputStream.CanSeek) { flags |= HeaderFlags.UsePostDataDescriptor; if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA) { flags |= HeaderFlags.Bit1; // eos marker } } OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)flags), 0, 2); OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)explicitZipCompressionInfo), 0, 2); // zipping method OutputStream.Write(DataConverter.LittleEndian.GetBytes(zipWriterEntryOptions.ModificationDateTime.DateTimeToDosTime()), 0, 4); // zipping date and time OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12); // unused CRC, un/compressed size, updated later OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2); // extra length OutputStream.Write(encodedFilename, 0, encodedFilename.Length); return(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length); }
private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64) { // We err on the side of caution until the zip specification clarifies how to support this if (!OutputStream.CanSeek && useZip64) { throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams"); } var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType); byte[] encodedFilename = WriterOptions.ArchiveEncoding.Encode(filename); OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate) { if (OutputStream.CanSeek && useZip64) { OutputStream.Write(new byte[] { 45, 0 }, 0, 2); //smallest allowed version for zip64 } else { OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible } } else { OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA } HeaderFlags flags = Equals(WriterOptions.ArchiveEncoding.GetEncoding(), Encoding.UTF8) ? HeaderFlags.UTF8 : 0; if (!OutputStream.CanSeek) { flags |= HeaderFlags.UsePostDataDescriptor; if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA) { flags |= HeaderFlags.Bit1; // eos marker } } OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)flags), 0, 2); OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)explicitZipCompressionInfo), 0, 2); // zipping method OutputStream.Write(DataConverter.LittleEndian.GetBytes(zipWriterEntryOptions.ModificationDateTime.DateTimeToDosTime()), 0, 4); // zipping date and time OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12); // unused CRC, un/compressed size, updated later OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length var extralength = 0; if (OutputStream.CanSeek && useZip64) { extralength = 2 + 2 + 8 + 8; } OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)extralength), 0, 2); // extra length OutputStream.Write(encodedFilename, 0, encodedFilename.Length); if (extralength != 0) { OutputStream.Write(new byte[extralength], 0, extralength); // reserve space for zip64 data entry.Zip64HeaderOffset = (ushort)(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length); } return(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length + extralength); }