Exemple #1
0
 protected override void Dispose(bool disposing)
 {
     if (this._disposed)
     {
         return;
     }
     if (disposing && !this._exceptionPending)
     {
         this._FinishCurrentEntry();
         this._directoryNeededZip64 = ZipOutput.WriteCentralDirectoryStructure(this._outputStream, this._entriesWritten.Values, 1u, this._zip64, this.Comment, new ZipContainer(this));
         CountingStream countingStream = this._outputStream as CountingStream;
         Stream         stream;
         if (countingStream != null)
         {
             stream = countingStream.WrappedStream;
             countingStream.Dispose();
         }
         else
         {
             stream = this._outputStream;
         }
         if (!this._leaveUnderlyingStreamOpen)
         {
             stream.Dispose();
         }
         this._outputStream = null;
     }
     this._disposed = true;
 }
Exemple #2
0
 private void _FinishCurrentEntry()
 {
     if (this._currentEntry != null)
     {
         if (this._needToWriteEntryHeader)
         {
             this._InitiateCurrentEntry(true);
         }
         this._currentEntry.FinishOutputStream(this._outputStream, this._outputCounter, this._encryptor, this._deflater, this._entryOutputStream);
         this._currentEntry.PostProcessOutput(this._outputStream);
         if (this._currentEntry.OutputUsedZip64.HasValue)
         {
             this._anyEntriesUsedZip64 |= this._currentEntry.OutputUsedZip64.Value;
         }
         this._outputCounter     = null;
         this._encryptor         = (this._deflater = null);
         this._entryOutputStream = null;
     }
 }
        /// <summary>
        ///   Save the zip archive to the specified stream.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   The <c>ZipFile</c> instance is written to storage - typically a zip file
        ///   in a filesystem, but using this overload, the storage can be anything
        ///   accessible via a writable stream - only when the caller calls <c>Save</c>.
        /// </para>
        ///
        /// <para>
        ///   Use this method to save the zip content to a stream directly.  A common
        ///   scenario is an ASP.NET application that dynamically generates a zip file
        ///   and allows the browser to download it. The application can call
        ///   <c>Save(Response.OutputStream)</c> to write a zipfile directly to the
        ///   output stream, without creating a zip file on the disk on the ASP.NET
        ///   server.
        /// </para>
        ///
        /// <para>
        ///   Be careful when saving a file to a non-seekable stream, including
        ///   <c>Response.OutputStream</c>. When DotNetZip writes to a non-seekable
        ///   stream, the zip archive is formatted in such a way that may not be
        ///   compatible with all zip tools on all platforms.  It's a perfectly legal
        ///   and compliant zip file, but some people have reported problems opening
        ///   files produced this way using the Mac OS archive utility.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        ///
        ///   This example saves the zipfile content into a MemoryStream, and
        ///   then gets the array of bytes from that MemoryStream.
        ///
        /// <code lang="C#">
        /// using (var zip = new Pathfinding.Ionic.Zip.ZipFile())
        /// {
        ///     zip.CompressionLevel= Pathfinding.Ionic.Zlib.CompressionLevel.BestCompression;
        ///     zip.Password = "******";
        ///     zip.Encryption = EncryptionAlgorithm.WinZipAes128;
        ///     zip.AddFile(sourceFileName);
        ///     MemoryStream output = new MemoryStream();
        ///     zip.Save(output);
        ///
        ///     byte[] zipbytes = output.ToArray();
        /// }
        /// </code>
        /// </example>
        ///
        /// <example>
        /// <para>
        ///   This example shows a pitfall you should avoid. DO NOT read
        ///   from a stream, then try to save to the same stream.  DO
        ///   NOT DO THIS:
        /// </para>
        ///
        /// <code lang="C#">
        /// using (var fs = new FileSteeam(filename, FileMode.Open))
        /// {
        ///   using (var zip = Pathfinding.Ionic.Zip.ZipFile.Read(inputStream))
        ///   {
        ///     zip.AddEntry("Name1.txt", "this is the content");
        ///     zip.Save(inputStream);  // NO NO NO!!
        ///   }
        /// }
        /// </code>
        ///
        /// <para>
        ///   Better like this:
        /// </para>
        ///
        /// <code lang="C#">
        /// using (var zip = Pathfinding.Ionic.Zip.ZipFile.Read(filename))
        /// {
        ///     zip.AddEntry("Name1.txt", "this is the content");
        ///     zip.Save();  // YES!
        /// }
        /// </code>
        ///
        /// </example>
        ///
        /// <param name="outputStream">
        ///   The <c>System.IO.Stream</c> to write to. It must be
        ///   writable. If you created the ZipFile instanct by calling
        ///   ZipFile.Read(), this stream must not be the same stream
        ///   you passed to ZipFile.Read().
        /// </param>
        public void Save(Stream outputStream)
        {
            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }
            if (!outputStream.CanWrite)
            {
                throw new ArgumentException("Must be a writable stream.", "outputStream");
            }

            // if we had a filename to save to, we are now obliterating it.
            _name = null;

            _writestream = new CountingStream(outputStream);

            _contentsChanged   = true;
            _fileAlreadyExists = false;
            Save();
        }
Exemple #4
0
        public static bool WriteCentralDirectoryStructure(Stream s, ICollection <ZipEntry> entries, uint numSegments, Zip64Option zip64, string comment, ZipContainer container)
        {
            ZipSegmentedStream zipSegmentedStream = s as ZipSegmentedStream;

            if (zipSegmentedStream != null)
            {
                zipSegmentedStream.ContiguousWrite = true;
            }
            long num = 0L;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                foreach (ZipEntry current in entries)
                {
                    if (current.IncludedInMostRecentSave)
                    {
                        current.WriteCentralDirectoryEntry(memoryStream);
                    }
                }
                byte[] array = memoryStream.ToArray();
                s.Write(array, 0, array.Length);
                num = (long)array.Length;
            }
            CountingStream countingStream = s as CountingStream;
            long           num2           = (countingStream == null) ? s.Position : countingStream.ComputedPosition;
            long           num3           = num2 - num;
            uint           num4           = (zipSegmentedStream == null) ? 0u : zipSegmentedStream.CurrentSegment;
            long           num5           = num2 - num3;
            int            num6           = ZipOutput.CountEntries(entries);
            bool           flag           = zip64 == Zip64Option.Always || num6 >= 65535 || num5 > (long)((ulong)-1) || num3 > (long)((ulong)-1);

            byte[] array3;
            if (flag)
            {
                if (zip64 == Zip64Option.Default)
                {
                    StackFrame stackFrame = new StackFrame(1);
                    if (stackFrame.GetMethod().DeclaringType == typeof(ZipFile))
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    }
                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
                }
                else
                {
                    byte[] array2 = ZipOutput.GenZip64EndOfCentralDirectory(num3, num2, num6, numSegments);
                    array3 = ZipOutput.GenCentralDirectoryFooter(num3, num2, zip64, num6, comment, container);
                    if (num4 != 0u)
                    {
                        uint value = zipSegmentedStream.ComputeSegment(array2.Length + array3.Length);
                        int  num7  = 16;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 += 4;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 = 60;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                        num7 += 4;
                        num7 += 8;
                        Array.Copy(BitConverter.GetBytes(value), 0, array2, num7, 4);
                    }
                    s.Write(array2, 0, array2.Length);
                }
            }
            else
            {
                array3 = ZipOutput.GenCentralDirectoryFooter(num3, num2, zip64, num6, comment, container);
            }
            if (num4 != 0u)
            {
                ushort value2 = (ushort)zipSegmentedStream.ComputeSegment(array3.Length);
                int    num8   = 4;
                Array.Copy(BitConverter.GetBytes(value2), 0, array3, num8, 2);
                num8 += 2;
                Array.Copy(BitConverter.GetBytes(value2), 0, array3, num8, 2);
                num8 += 2;
            }
            s.Write(array3, 0, array3.Length);
            if (zipSegmentedStream != null)
            {
                zipSegmentedStream.ContiguousWrite = false;
            }
            return(flag);
        }